commit c6d26f18e9faf8fedd54cb127b71bbeb1dd528fc Author: lijh Date: Tue Sep 30 15:16:37 2025 +0800 20250930 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c102fe8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,389 @@ +# ---> VisualStudio +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*[.json, .xml, .info] + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# ---> C++ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + diff --git a/CONNOR_ITK/CONNOR_ITK.vcxproj b/CONNOR_ITK/CONNOR_ITK.vcxproj new file mode 100644 index 0000000..d97ac44 --- /dev/null +++ b/CONNOR_ITK/CONNOR_ITK.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {A5936B6A-CCDE-41C6-A5EC-5D8CAF769F7F} + CONNOR_ITK + 10.0.19041.0 + RB_ITK + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + DynamicLibrary + true + MultiByte + v140 + + + DynamicLibrary + false + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + + + .dll + + + + Level3 + Disabled + true + + + + + Level3 + Disabled + true + C:\Siemens\Teamcenter13\include;C:\Siemens\Teamcenter13\include_cpp;$(SolutionDir)OCI\include;%(AdditionalIncludeDirectories) + ProgramDatabase + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;IPLIB=none;%(PreprocessorDefinitions) + + + C:\Siemens\Teamcenter13\lib\*.lib;%(AdditionalDependencies) + $(OutDir)\ml.dll + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + D:\WorkEnvironment\ocilib-4.7.2-windows\include;D:\WorkEnvironment\tc12ITK\dflittk\oci\include;D:\WorkEnvironment\tc12ITK\dflittk\include_cpp;D:\WorkEnvironment\tc12ITK\dflittk\include;C:\Users\admin\Desktop\vcpkg\downloads\openssl-openssl-openssl-3.1.0\openssl-openssl-3.1.0\include\openssl;D:\项目\人本\人本\tc12ITK\dflittk\include;D:\项目\人本\人本\tc12ITK\dflittk\include_cpp;D:\项目\人本\人本\tc12ITK\dflittk\oci\include;D:\项目\人本\人本\jsoncpp-master\include\json;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;IPLIB=none;%(PreprocessorDefinitions) + + + true + true + $(OutDir)\rb.dll + D:\项目\人本\人本\tc12ITK\dflittk\lib\*.lib;D:\WorkEnvironment\tc12ITK\dflittk\lib\*.lib;D:\WorkEnvironment\ocilib-4.7.2-windows\lib64\*.lib;%(AdditionalDependencies) + Console + /FORCE:MULTIPLE %(AdditionalOptions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CONNOR_ITK/CONNOR_ITK.vcxproj.filters b/CONNOR_ITK/CONNOR_ITK.vcxproj.filters new file mode 100644 index 0000000..0b7d1c6 --- /dev/null +++ b/CONNOR_ITK/CONNOR_ITK.vcxproj.filters @@ -0,0 +1,121 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {ca041e83-7fab-47f9-b6e5-089441e62ecf} + + + {48795282-4973-45c1-8088-ec3dc4f3c98c} + + + {6f6034c0-2af0-4b17-bb50-1d9606d6c892} + + + {6836d814-428d-41e9-b85b-7377b8514455} + + + + + common + + + common + + + common + + + tinyxml + + + tinyxml + + + tinyxml + + + tinyxml + + + Util + + + Util + + + handler + + + handler + + + handler + + + handler + + + handler + + + handler + + + handler + + + handler + + + handler + + + handler + + + common + + + common + + + handler + + + + + 头文件 + + + 头文件 + + + common + + + tinyxml + + + tinyxml + + + 头文件 + + + common + + + common + + + common + + + common + + + \ No newline at end of file diff --git a/CONNOR_ITK/OracleDB.cpp b/CONNOR_ITK/OracleDB.cpp new file mode 100644 index 0000000..db2f8f5 --- /dev/null +++ b/CONNOR_ITK/OracleDB.cpp @@ -0,0 +1,156 @@ +// OracleDB.cpp +#include "OracleDB.h" +#include +#include +#include +#include +#include + +OracleDB::OracleDB() : conn(nullptr), stmt(nullptr), isConnected(false) {} + +OracleDB::~OracleDB() { + disconnect(); +} + +bool OracleDB::connect(const char* user, const char* pwd, const char* host) { + if (isConnected) return true; + + + + // + conn = OCI_ConnectionCreate(host, user, pwd, OCI_SESSION_DEFAULT); + if (!conn) { + printf("ݿʧ: %s\n", OCI_GetLastError() ? OCI_ErrorGetString(OCI_GetLastError()) : "Unknown error"); + return false; + } + + stmt = OCI_StatementCreate(conn); + if (!stmt) { + printf("ʧ\n"); + OCI_ConnectionFree(conn); + conn = nullptr; + return false; + } + + isConnected = true; + printf("ݿӳɹ\n"); + return true; +} + +void OracleDB::disconnect() { + if (stmt) { + OCI_StatementFree(stmt); + stmt = nullptr; + } + if (conn) { + OCI_ConnectionFree(conn); + conn = nullptr; + } + isConnected = false; +} + +int OracleDB::executeQuery( + const char* sql, + int* outputColumn, + int* outputRow, + char**** outputValue +) { + // ʼ + *outputColumn = 0; + *outputRow = 0; + *outputValue = nullptr; + + printf("ʼ\n"); + + if (!isConnected || !stmt) { + printf("ݿδӻЧ\n"); + return -1; + } + + printf("ݿӳɹ\n"); + + if (!OCI_ExecuteStmt(stmt, sql)) { + printf("SQLִʧ: %s\n", OCI_ErrorGetString(OCI_GetLastError())); + return -1; + } + + printf("SQLִгɹ\n"); + + OCI_Resultset* rs = OCI_GetResultset(stmt); + if (!rs) { + printf("޷ȡ\n"); + return -1; + } + + printf("ȡɹ\n"); + + int colCount = (int)OCI_GetColumnCount(rs); + printf(": %d\n", colCount); + + // ʹ vector ʱ洢 + std::vector> tempData; + + int rowCount = 0; + while (OCI_FetchNext(rs)) { + std::vector row; + for (int j = 0; j < colCount; j++) { + const char* val = OCI_GetString(rs, j + 1); + if (val) { + row.push_back(std::string(val)); + } + else { + row.push_back("NULL"); + } + } + tempData.push_back(row); + rowCount++; + } + + printf("ɣ: %d\n", rowCount); + + // outputValue + char*** result = (char***)calloc(rowCount, sizeof(char**)); + if (!result) { + printf("ڴʧ\n"); + return -1; + } + printf("Ϊڴ\n"); + + for (int i = 0; i < rowCount; i++) { + result[i] = (char**)calloc(colCount, sizeof(char*)); + if (!result[i]) { + // ѷڴ + for (int j = 0; j < i; j++) { + for (int k = 0; k < colCount; k++) { + free(result[j][k]); + } + free(result[j]); + } + free(result); + printf("ڴʧ\n"); + return -1; + } + printf("Ϊ %d зڴ\n", i + 1); + + for (int j = 0; j < colCount; j++) { + const std::string& val = tempData[i][j]; + result[i][j] = (char*)malloc(val.length() + 1); + if (result[i][j]) { + strcpy(result[i][j], val.c_str()); + printf("Ƶ %d е %d е: %s\n", i + 1, j + 1, result[i][j]); + } + else { + result[i][j] = nullptr; + printf("ڴʧܣõ %d е %d Ϊָ\n", i + 1, j + 1); + } + } + } + + // + *outputColumn = colCount; + *outputRow = rowCount; + *outputValue = result; + + printf("executeQuery ɹ\n"); + return 0; // ɹ +} \ No newline at end of file diff --git a/CONNOR_ITK/OracleDB.h b/CONNOR_ITK/OracleDB.h new file mode 100644 index 0000000..c34281e --- /dev/null +++ b/CONNOR_ITK/OracleDB.h @@ -0,0 +1,40 @@ +// OracleDB.h +#ifndef ORACLEDB_H +#define ORACLEDB_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "ocilib2.h" +#ifdef __cplusplus +} +#endif + +class OracleDB { +private: + OCI_Connection* conn; + OCI_Statement* stmt; + bool isConnected; + +public: + OracleDB(); + ~OracleDB(); + + // ݿ + bool OracleDB::connect(const char* user, const char* pwd, const char* host); + + // ִвѯҪĽӿ + int executeQuery( + const char* sql, + int* outputColumn, + int* outputRow, + char**** outputValue + ); + + // Ͽ + void disconnect(); +}; + +#endif // ORACLEDB_H \ No newline at end of file diff --git a/CONNOR_ITK/RB_AutoSignServer.cpp b/CONNOR_ITK/RB_AutoSignServer.cpp new file mode 100644 index 0000000..5af614f --- /dev/null +++ b/CONNOR_ITK/RB_AutoSignServer.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epm_handler_common.h" + +#include "RB_AutoSignServer.h"; +#define DOFREE(obj) \ +{ \ + if(obj) \ + { \ + MEM_free(obj); \ + obj = NULL; \ + } \ +} + +//ȡ̽ڵԶ +int RB_AutoSignServer(void *returnValue) +{ + int ifail = 0; + char * myResult = NULL, + *myType = NULL; + char * signoffUid = NULL; + char * parentUid = NULL; + string resultString; + tag_t parentTag = NULLTAG, signoffTag = NULLTAG; + POM_AM__set_application_bypass(true); + ITKCALL(ifail = USERARG_get_string_argument(&signoffUid)); + ITKCALL(ifail = USERARG_get_string_argument(&parentUid)); + myResult = (char *)MEM_alloc(8 * sizeof(char)); + printf("signoffUid=%s\n", signoffUid); + printf("parentUid=%s\n", parentUid); + tc_strcpy(myResult, "-1"); + ITK__convert_uid_to_tag(parentUid, &parentTag); + if (parentTag == NULLTAG) { + tc_strcpy(myResult, "0"); + } + ITK__convert_uid_to_tag(signoffUid, &signoffTag); + if (signoffTag == NULLTAG) { + tc_strcpy(myResult, "0"); + } + char * taskname = NULL, *type = NULL; + ITKCALL(AOM_ask_value_string(parentTag, "object_type", &type)); + printf("name=%s\n", taskname); + printf("type=%s\n", type); + if (strcmp(type, "EPMReviewTask") == 0) + { + //int num = 0; + //tag_t *sub_tags = NULL; + //ITKCALL(EPM_ask_sub_tasks(task_tag, &num, &sub_tags)); + //for (int j = 0; j < num; j++) + //{ + //char * taskname2 = NULL, *type2 = NULL; + //ITKCALL(EPM_ask_name2(sub_tags[j], &taskname2)); + //ITKCALL(AOM_ask_value_string(sub_tags[j], "object_type", &type2)); + //if (strcmp(type2, "EPMPerformSignoffTask") == 0) + //{ + //printf("name2=%s,type2=%s\n", taskname2, type2); + ITKCALL(EPM_promote_task(parentTag, "")); + //} + //DOFREE(taskname2); + //DOFREE(type2); + + // } + //DOFREE(sub_tags); + } + DOFREE(taskname); + DOFREE(type); + POM_AM__set_application_bypass(false); + /*if (parentTag != NULLTAG && signoffTag != NULLTAG) { + POM_AM__set_application_bypass(true); + char *realState = NULL; + logical isPexist = false; + logical isAexist = false; + ITKCALL(POM_instance_exists(parentTag, &isPexist)); + ITKCALL(POM_instance_exists(signoffTag, &isAexist)); + if (isPexist && isAexist) { + ITKCALL(ifail = AOM_refresh(parentTag, 0)); + ITKCALL(ifail = AOM_refresh(signoffTag, 0)); + ITKCALL(AOM_ask_value_string(parentTag, "real_state", &realState)); + printf("realState=%s\n", realState); + if (strcmp(realState, "Started") == 0) { + ITKCALL(ifail = EPM_set_task_decision2(parentTag, signoffTag, CR_approve_decision, "")); + if (ifail == ITK_ok) { + tc_strcpy(myResult, "0"); + printf("ִɹ"); + } + else { + printf("ִʧܣ"); + } + //MEM_free(realState); + //realState = NULL; + } + else if (strcmp(realState, "Completed") == 0) { + tc_strcpy(myResult, "0"); + printf("ڵ״̬Ϊɣ\n"); + } + MEM_free(realState); + realState = NULL; + POM_AM__set_application_bypass(false); + } + else { + tc_strcpy(myResult, "0"); + printf("󲻴ڣ\n"); + } + } + */ + *((char**)returnValue) = myResult; + return 0; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_AutoSignServer.h b/CONNOR_ITK/RB_AutoSignServer.h new file mode 100644 index 0000000..68e4ab8 --- /dev/null +++ b/CONNOR_ITK/RB_AutoSignServer.h @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include ; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include ; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int RB_AutoSignServer(void *returnValue); \ No newline at end of file diff --git a/CONNOR_ITK/RB_BOM_TO_ERP.cpp b/CONNOR_ITK/RB_BOM_TO_ERP.cpp new file mode 100644 index 0000000..d3d7ec0 --- /dev/null +++ b/CONNOR_ITK/RB_BOM_TO_ERP.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocilib.h" +#include "connor_itk_util.h" +#include "epm_handler_common.h" +using namespace std; +#define EPM_HANDLER_COMMON +#define MAX_PATH_LENGTH 200 +#define MAX_PRINTLINE_LENGTH 400000 + +int RB_BOM_TO_ERP(EPM_action_message_t msg) { + + tag_t task_tag = NULL_TAG, + root_task_tag = NULLTAG, + *attachments;; + task_tag = msg.task; + int att_cnt = 0, ifail = 0; + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + WriteLog("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + CloseLog(); + return 1; + } + printf("------------------------------------------------------------------------------------"); + printf("========================="); + printf("RB_BOM_TO_ERP start"); + printf("========================="); + + EPM_ask_root_task(task_tag, &root_task_tag); + EPM_ask_attachments(root_task_tag, EPM_target_attachment, &att_cnt, &attachments); + printf("ĿµĶ%d", att_cnt); + + + char* tempValue = NULL; + char taskpuid[56] = "\0"; + ITK__convert_tag_to_uid(task_tag, &tempValue); + tc_strcpy(taskpuid, tempValue); + + time_t curtime1; + time(&curtime1); + tm* nowtime1 = localtime(&curtime1); + string dealBeginTime; + dealBeginTime.append(std::to_string(1900 + nowtime1->tm_year)).append("-").append(std::to_string(1 + nowtime1->tm_mon)).append("-").append(std::to_string(nowtime1->tm_mday)).append(" ").append(std::to_string(nowtime1->tm_hour)).append(":").append(std::to_string(nowtime1->tm_min)).append(":").append(std::to_string(nowtime1->tm_sec)); + + if (ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]))//"tc11","infodba","//172.16.50.40/tc11" "TC12","infodba","172.16.68.13/tc1" + { + printf("ʾ:мݱʧ\n"); + return ifail; + } + else { + printf("ʾ:мݱʳɹ\n"); + char sql1[1024] = "\0"; + + + sprintf(sql1, "insert into RB_BOM_TO_ERP(flowid,status,starttime) values ('%s','%s',TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS'))", taskpuid, "0",dealBeginTime.c_str()); + printf("ʾ:sql1==%s\n", sql1); + if (ExecuteSQLNoInputParam(sql1) == -1) + { + printf("ʾ:ݲ ʧ, %s \n", sql1); + ifail = 1; + } + else { + ExecuteSQLNoInputParam("commit"); + } + } + + + DOFREE(attachments); + printf("========================="); + printf("RB_BOM_TO_ERP end"); + printf("========================="); + return ifail; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_CheckForCompletion.cxx b/CONNOR_ITK/RB_CheckForCompletion.cxx new file mode 100644 index 0000000..3c60a87 --- /dev/null +++ b/CONNOR_ITK/RB_CheckForCompletion.cxx @@ -0,0 +1,69 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" + +/** + * + * @handlerType: ActionHandler + * @handlerName: RB_CheckForCompletion + * @Description: 1ƽڵʱ :Ŀ[汾RB3_TaskPackageRevisionµ[RB3_TaskDeliverable]ϵݲΪ + * 2Ŀ[汾]µ[ĿϵRB3_XMGX]ϵµ[Ŀ汾RB3_XMKFRevision]µ [ϹϵRB3_WLGX]ݲΪ + * [] [Ϲϵ] һΪգͨ[] [Ϲϵ] ݲΪա: ڵͨ + * @author hcj + * @date 202419 + * + */ +int RB_CheckForCompletion(EPM_action_message_t msg) +{ + int attachments_num = 0; + tag_t rootTask = NULLTAG; + tag_t *attachments = NULLTAG; + char* errorMessage = "ϹϵݲΪ"; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + printf("ʼѭĿеĶ\n"); + for (int i = 0; i < attachments_num; i++) + { + char* attType; + ITKCALL(AOM_ask_value_string(attachments[i], "object_type", &attType)); + printf("ȡ%sǷRB3_TaskPackageRevisionƥ\n", attType); + if (strcmp(attType,"RB3_TaskPackageRevision")) + { + printf("ƥ\nʼĿRB3_TaskPackageRevisionµRB3_TaskDeliverableϵǷΪ\n"); + //Ŀ[汾RB3_TaskPackageRevisionµ[RB3_TaskDeliverable]ϵǷΪ + int checkNum = 0; + tag_t* checkObj; + ITKCALL(AOM_ask_value_tags(attachments[i], "RB3_TaskDeliverable", &checkNum, &checkObj)); + if (checkNum == 0) { + printf("Ϊգʾ˳\n"); + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + return 1; + } + printf("汾µRB3_XMGXϵµ[RB3_XMKFRevision]µ [ϹϵRB3_WLGX]ǷΪ\n"); + //汾µRB3_XMGXϵµ[RB3_XMKFRevision]µ [ϹϵRB3_WLGX]ǷΪ + int num = 0; + tag_t* obj; + ITKCALL(AOM_ask_value_tags(attachments[i], "RB3_XMGX", &num, &obj)); + for (int j = 0; j < num; j++) + { + printf("ʼѭȡRB3_XMGXϵµĶ\n"); + char* taskPType; + ITKCALL(AOM_ask_value_string(obj[j], "object_type", &taskPType)); + printf("ƥ%sǷRB3_XMKFRevision\n", taskPType); + if (strcmp(taskPType, "RB3_XMKFRevision")) + { + printf("ƥ\n"); + int checkTaskNum = 0; + tag_t* checkTaskObj; + ITKCALL(AOM_ask_value_tags(obj[j], "RB3_WLGX", &checkTaskNum, &checkTaskObj)); + if (checkTaskNum == 0) { + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + return 1; + } + } + } + } + } + return ITK_ok; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_PLM2LIMS_JCSY.cpp b/CONNOR_ITK/RB_PLM2LIMS_JCSY.cpp new file mode 100644 index 0000000..6c0de67 --- /dev/null +++ b/CONNOR_ITK/RB_PLM2LIMS_JCSY.cpp @@ -0,0 +1,506 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" +#include +#include +#include "ocilib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ITK_err 919821 +using namespace std; + + +char* concat(char** s, int size) { + int length = 0; + for (int i = 0; i < size; i++) { + length += strlen(s[i]); + } + char* result = new char[length + 1]; + int index = 0; + for (int i = 0; i < size; i++) { + int len = strlen(s[i]); + memcpy(result + index, s[i], len); + index += len; + } + result[length] = '\0'; + return result; +} + +// Ƴַ˵Ŀհַ +string trim(string str) { + str.erase(0, str.find_first_not_of(" \n\r\t")); + str.erase(str.find_last_not_of(" \n\r\t") + 1); + return str; +} +// ַijַָɶӴ +vector split(string str, char delimiter) { + vector tokens; + stringstream ss(str); + string token; + while (getline(ss, token, delimiter)) { + tokens.push_back(trim(token)); + } + return tokens; +} +// JSONַеֵַ +string parseString(string str) { + str.erase(0, 1); // Ƴͷ˫ + str.erase(str.size() - 1); // Ƴβ˫ + return str; +} +// JSONַеֵ +int64_t parseInteger(string str) { + return stoll(trim(str)); +} +void morechat(char **& values,char *& result) { + std::string values_str; + for (int i = 0; *(values + i) != nullptr; i++) { // ʹ˫ָԪ + if (i > 0) { + values_str += ", "; + } + values_str += *(values + i); + } + result = new char[values_str.size() + 1]; + std::strcpy(result, values_str.c_str()); + std::cout << result << std::endl; + delete[] result; + delete[] values; // ǵͷ char** ͵ָ +} + +static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) { + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; +} +size_t writeFunction(void* ptr, size_t size, size_t nmemb, std::string* data) { + data->append((char*)ptr, size * nmemb); + return size * nmemb; +} + +void Split(string strArg, string spliter, vector &ans) +{ + ans.clear(); + size_t index0 = 0; + string one_arg; + if (strArg.find_first_not_of(' ') == string::npos) + strArg = ""; + while (strArg.size() > 0) + { + index0 = strArg.find_first_of(spliter); + if (index0 != string::npos) + { + one_arg = strArg.substr(0, index0); + strArg = strArg.substr(index0 + 1); + ans.push_back(one_arg); + } + else + { + ans.push_back(strArg); + break; + } + } +} + +int RB_PLM2LIMS_JCSY(EPM_action_message_t msg) +{ + auto logFile = std::make_unique("D:\\TCTOLIMS\\output.log", std::ios_base::app); + logFile->is_open(); + auto now = std::chrono::system_clock::now(); + std::time_t time = std::chrono::system_clock::to_time_t(now); + std::string timeStr = std::ctime(&time); + *logFile << "[" << timeStr.substr(0, timeStr.size() - 1) << "] "; + *logFile << "=========================TCίеϢLIMS===================" << std::endl; + POM_AM__set_application_bypass(true); // · + *logFile << "=========================·===================" << std::endl; + printf("=========================TCίеϢLIMS===================\n"); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, *attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + //ȡ + char *url = NULL, *name = NULL, *password = NULL; + char *argflag = NULL, *argvalue = NULL, *arg = NULL; + int arg_cnt = TC_number_of_arguments(msg.arguments); + char* uid; + char *endResult; + printf("Ϊ%d\n", arg_cnt); + *logFile << "Ϊ" << std::endl; + if (arg_cnt > 0) + { + + for (int i = 0; i valueMap;//ͳƼ + //orderList + std::map orderValue; + std::map> orderMap; + //ѡȡ + *logFile << "ѡRB_PLM2LIMS_JCSYȡ" << std::endl; + printf("ѡRB_PLM2LIMS_JCSYȡ\n"); + int pref_cnt = 0; + char** pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_PLM2LIMS_JCSY", &pref_cnt, &pref_vals); + if (pref_cnt > 0) { + for (int i = 0; i < pref_cnt; i++) { + char* getValue = ""; + char* val = pref_vals[i]; + *logFile << "ʼַָ" << std::endl; + *logFile << val << std::endl; + printf("ʼָѡ%s\n", val); + printf("ʼַָ\n"); + vector ans; + Split(val, "-", ans); + if (ans.size() > 0) { + for (int j = 0; j < ans.size(); j++) { + if (stricmp("true", (char*)ans[2].c_str()) == 0) { //lov + *logFile << "lov" << std::endl; + //Log::info("lov"); + if (stricmp("true", (char*)ans[3].c_str()) == 0) { //ʵֵ + *logFile << "ʵֵ" << std::endl; + //Log::info("ʵֵ"); + if (stricmp("true", (char*)ans[4].c_str()) == 0) { //װorderList + *logFile << "װorderList" << std::endl; + //Log::info("װorderList"); + int call; + if (stricmp(ans[5].c_str(), "string") == 0) { + *logFile << "ȡַ" << std::endl; + ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue)); + } + else if (stricmp(ans[5].c_str(), "date") == 0) { + *logFile << "ȡ" << std::endl; + date_t getdate; + ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate)); + sprintf(getValue, "%d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day); + } + else if (stricmp(ans[5].c_str(), "array") == 0) { + *logFile << "ȡ" << std::endl; + int num; char** getValues; + ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues)); + getValue = concat(getValues, num); + } + else { + getValue = "***"; + } + orderValue[ans[0].c_str()] = getValue; + } + else { //װorderList + //Log::info("װorderList"); + *logFile << "װorderList" << std::endl; + int call; + if (stricmp(ans[5].c_str(), "string") == 0) { + *logFile << "ȡַ" << std::endl; + ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue)); + } + else if (stricmp(ans[5].c_str(), "date") == 0) { + *logFile << "ȡ" << std::endl; + date_t getdate; + ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate)); + sprintf(getValue, "%d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day); + } + else if (stricmp(ans[5].c_str(), "array") == 0) { + *logFile << "ȡ" << std::endl; + int num; char** getValues; + ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues)); + getValue = concat(getValues, num); + } + else { + getValue = "***"; + } + valueMap[ans[0].c_str()] = getValue; + } + } + else { //ʾֵ + *logFile << "ʾֵ" << std::endl; + //Log::info("ʾֵ"); + if (stricmp("true", (char*)ans[4].c_str()) == 0) { //װorderList + *logFile << "װorderList" << std::endl; + //Log::info("װorderList"); + int call; + if (stricmp(ans[5].c_str(), "string") == 0) { + *logFile << "ȡַ" << std::endl; + ITKCALL(call = AOM_UIF_ask_value(attachments[r], ans[1].c_str(), &getValue)); + } + else if (stricmp(ans[5].c_str(), "array") == 0) { + *logFile << "ȡ" << std::endl; + int num; char** getValues; + ITKCALL(call = AOM_UIF_ask_values(attachments[r], ans[1].c_str(), &num, &getValues)); + getValue = concat(getValues, num); + } + else { + getValue = "***"; + } + orderValue[ans[0].c_str()] = getValue; + } + else { //װorderList + *logFile << "װorderList" << std::endl; + //Log::info("װorderList"); + int call; + if (stricmp(ans[5].c_str(), "string") == 0) { + *logFile << "ȡַ" << std::endl; + ITKCALL(call = AOM_UIF_ask_value(attachments[r], ans[1].c_str(), &getValue)); + } + else if (stricmp(ans[5].c_str(), "array") == 0) { + *logFile << "ȡ" << std::endl; + int num; char** getValues; + ITKCALL(call = AOM_UIF_ask_values(attachments[r], ans[1].c_str(), &num, &getValues)); + getValue = concat(getValues, num); + } + else { + getValue = "***"; + } + valueMap[ans[0].c_str()] = getValue; + } + } + } + else { //lov + *logFile << "lov" << std::endl; + //Log::info("lov"); + if (stricmp("true", (char*)ans[4].c_str()) == 0) { //װorderList + *logFile << "װorderList" << std::endl; + //Log::info("װorderList"); + int call; + if (stricmp(ans[5].c_str(), "string") == 0) { + *logFile << "ȡַ" << std::endl; + ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue)); + } + else if (stricmp(ans[5].c_str(), "date") == 0) { + *logFile << "ȡ" << std::endl; + date_t getdate; + *logFile << "ʼֵ" << std::endl; + ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate)); + *logFile << "ֵ" << std::endl; + printf("getdate %d", getdate); + char fileDate[128] = ""; + sprintf_s(fileDate, "%04d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day); + *logFile << "ֵɹ" << std::endl; + *logFile << fileDate << std::endl; + getValue = fileDate; + } + else if (stricmp(ans[5].c_str(), "array") == 0) { + *logFile << "ȡ" << std::endl; + int num; char** getValues; + ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues)); + getValue = concat(getValues, num); + } + else { + getValue = "***"; + } + orderValue[ans[0].c_str()] = getValue; + } + else { //װorderList + //Log::info("װorderList"); + *logFile << "װorderList" << std::endl; + int call; + if (stricmp(ans[5].c_str(), "string") == 0) { + *logFile << "ȡַ" << std::endl; + ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue)); + } + else if (stricmp(ans[5].c_str(), "date") == 0) { + *logFile << "ȡ" << std::endl; + date_t getdate; + *logFile << "ʼֵ" << std::endl; + ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate)); + *logFile << "ֵ" << std::endl; + printf("getdate %d", &getdate); + + char fileDate[128] = ""; + sprintf_s(fileDate, "%04d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day); + *logFile << "ֵɹ" << std::endl; + *logFile << fileDate << std::endl; + getValue = fileDate; + } + else if (stricmp(ans[5].c_str(), "array") == 0) { + *logFile << "ȡ" << std::endl; + int num; char** getValues; + ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues)); + getValue = concat(getValues, num); + } + else { + getValue = "***"; + } + valueMap[ans[0].c_str()] = getValue; + } + } + } + } + } + //orderList + *logFile << "orderList" << std::endl; + //Log::info("orderList"); + orderMap["orderList"] = orderValue; + //json + std::string jsonStr = "[{"; + // valueMapֵJSONַ + for (auto it = valueMap.begin(); it != valueMap.end(); it++) { + jsonStr += "\"" + it->first + "\":\"" + it->second + "\","; + } + // orderMapֵJSONַ + for (auto it = orderMap.begin(); it != orderMap.end(); it++) { + std::map order = it->second; + jsonStr += "\"" + it->first + "\":[{"; + for (auto it2 = order.begin(); it2 != order.end(); it2++) { + jsonStr += "\"" + it2->first + "\":\"" + it2->second + "\","; + } + if (order.size() > 0) { + jsonStr.erase(jsonStr.end() - 1); + } + jsonStr += "},"; + } + if (orderMap.size() > 0) { + jsonStr.erase(jsonStr.end() - 1); + } + jsonStr += "]}]"; + // JSONַ + std::cout << jsonStr << std::endl; + + + //json洢 + char jsonFile[1024] = ""; + strcat(jsonFile, "D:\\TCTOLIMS\\"); + strcat(jsonFile, uid); + strcat(jsonFile, "output.json"); + FILE* jsFile = fopen(jsonFile, "a+"); + + if (jsFile == NULL) { + // ļڻ޷򿪣Դ + *logFile << "ļڻ޷򿪣ʼ" << std::endl; + if (errno != EEXIST) { + return EXIT_FAILURE; + } + + jsFile = fopen(jsonFile, "w"); + if (jsFile == NULL) { + return EXIT_FAILURE; + } + *logFile << "ļɹʼдϢ" << std::endl; + } + else { + *logFile << "ļѴڣʼдϢ" << std::endl; + fclose(jsFile); + } + + std::ofstream ofs(jsonFile); + ofs << jsonStr; + ofs.close(); + *logFile << "ɹ" << std::endl; + //ʹjavaӿ + printf("ʼִcmd"); + *logFile << "ʼִcmd" << std::endl; + char cmd[1024] = ""; + strcpy(cmd, "java -jar D:\\Siemens\\Teamcenter12\\bin\\PostMain.jar"); + strcat(cmd, " "); + strcat(cmd, url); + strcat(cmd, " "); + strcat(cmd, uid); + *logFile << cmd << std::endl; + printf("\n%s\n", cmd); + system(cmd); + *logFile << "cmdִ" << std::endl; + //ȡصresultļ + string prefix = "D:\\TCTOLIMS\\"; + string suffix = "result.txt"; + string namepath = prefix +uid+ suffix; + *logFile << "ȡLIMSļ:" << namepath << std::endl; + std::ifstream file1(namepath); + if (!file1.is_open()) { + std::cerr << "Failed to open file!" << std::endl; + char* error = "δӦ"; + EMH_store_error_s2(EMH_severity_error, ITK_err, "ʾ", error); + return 1; + } + std::stringstream buffer1; + buffer1 << file1.rdbuf(); + std::string resultStr = buffer1.str(); + *logFile << resultStr << std::endl; + if (resultStr.find("false") != std::string::npos) { + //дֵ + AOM_lock(attachments[r]); + AOM_set_value_string(attachments[r], "rb3_limsInfo", resultStr.c_str()); + AOM_save(attachments[r]); + AOM_unlock(attachments[r]); + mees = mees + resultStr+"\n"; + + } + else { + //дֵ + AOM_lock(attachments[r]); + AOM_set_value_string(attachments[r], "rb3_limsInfo", resultStr.c_str()); + AOM_save(attachments[r]); + AOM_unlock(attachments[r]); + + } + } + } + POM_AM__set_application_bypass(false); // · + if (strcmp("",mees.c_str())!=0) { + EMH_store_error_s2(EMH_severity_error, ITK_err, "ʾ", mees.c_str()); + return 1; + } + else { + return ITK_ok; + } + + + } + return 0; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_SendErpBom.cxx b/CONNOR_ITK/RB_SendErpBom.cxx new file mode 100644 index 0000000..8222244 --- /dev/null +++ b/CONNOR_ITK/RB_SendErpBom.cxx @@ -0,0 +1,2187 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" + +void getItemJson(int index, tag_t topLine, tag_t BomLine, bool isStart, map typePropertyType, char parameters[100000]); +void getBomLineProperty(tag_t topLine, tag_t BomLine, map typePropertyType, char* bomBaseNum, char* sortString, char parameters[100000]); + +bool isSendBomStart = true; + +int RB_SendErpBom(EPM_action_message_t msg) +{ + printf("=========================BOM·ERP Start===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + //ȡ + char* argflag = NULL, * argvalue = NULL, * arg = NULL; + char messageUser[1024] = "", messageResult[1024] = ""; + int arg_cnt = TC_number_of_arguments(msg.arguments); + printf("Ϊ%d\n", arg_cnt); + if (arg_cnt > 0) + { + for (int i = 0; i < arg_cnt; i++) + { + //ȡһ0ʼ + arg = TC_next_argument(msg.arguments); + //ȡƺֵ + ifail = ITK_ask_argument_named_value((const char*)arg, &argflag, &argvalue); + if (stricmp(argflag, "ownerId") == 0) + { + if (argvalue != NULL) + { + strcpy(messageUser, argvalue); + } + } + else if (stricmp(argflag, "messageResult") == 0) + { + if (argvalue != NULL) + { + strcpy(messageResult, argvalue); + } + } + } + } + + vector messageUserValues; + + if (strstr(messageUser, ",") != NULL) + { + int vectorValueCount = 0; + char** vectorValueChar = new char* [64]; + split(messageUser, ",", vectorValueChar, &vectorValueCount); + for (int i = 0; i < vectorValueCount; i++) + { + messageUserValues.push_back(vectorValueChar[i]); + } + } + else + { + messageUserValues.push_back(messageUser); + } + + int pref_cnt = 0; + char** pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_BOMSendErpProperty", &pref_cnt, &pref_vals); + map typePropertyType; + for (int j = 0; j < pref_cnt; j++) + { + if (strstr(pref_vals[j], "-") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(pref_vals[j], "-", valueChar, &valueCount); + typePropertyType[valueChar[0]] = valueChar[1];// .insert(std::pair(valueChar[0], valueChar[1])); + } + } + + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + + char errorMessage[100000] = "";//д뵽ļֵ + for (int i = 0; i < attachments_num; i++) + { + char* itemType = NULL; + AOM_ask_value_string(attachments[i], "object_type", &itemType); + + printf("itemType%s Start===================\n", itemType); + + //˵ǰ汾Ķ + if (strcmp(itemType, "RB3_ZCRevision") != 0) + { + DOFREE(itemType); + continue; + } + + + isSendBomStart = true; + + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "getBomPropertys}}"); + strcat(parameters, "["); + + /*if ((strstr(itemType, "ZCRevision") == NULL) || (strstr(itemType, "Master") != NULL) + || (strstr(itemType, "master") != NULL) || (strstr(itemType, "BOM") != NULL) || (strstr(itemType, "bom") != NULL) || (strstr(itemType, "Bom") != NULL)) + { + DOFREE(itemType); + continue; + }*/ + + //ȡаĿBOM + vector bomLines; + //ȡ + tag_t top_line = NULLTAG, window = NULLTAG; + BOM_create_window(&window); + //öBOM + BOM_set_window_top_line(window, NULLTAG, attachments[i], NULLTAG, &top_line); + //ȡjsonַ + if (isSendBomStart) + { + getItemJson(-1, top_line, NULLTAG, isSendBomStart, typePropertyType, parameters); + //isStart = false; + } + else + { + getItemJson(-1, top_line, NULLTAG, isSendBomStart, typePropertyType, parameters); + } + + + DOFREE(itemType); + + strcat(parameters, "]"); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + //strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp.jar"); + strcat(cmd, "\" "); + // + cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + //strcat(cmd,"@"); + //strcat(cmd,handler_name); + printf("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + strResult = strResult.substr(0, iSize - 1); + printf("·ʧ\n"); + cout << strResult << endl; + strcat(errorMessage, strResult.c_str()); + if (strcmp(messageResult, "1") == 0) + { + ifail = 1; + } + } + } + + messageUserValues.clear(); + vector().swap(messageUserValues); + MEM_free(attachments); + tc_root_file = NULL; + pref_vals = NULL; + if (ifail == 1) + { + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + } + printf("=========================BOM·ERP End===================\n"); + return ifail; +} + +void getItemJson(int index, tag_t topLine, tag_t BomLine, bool isStart, map typePropertyType, char parameters[100000]) +{ + //ȡ汾 + int factoryNum = 0; + char** factoryValues = NULL; + char* localization_status; + logical master; + tag_t revisions = NULLTAG; + + AOM_ask_value_tag(topLine, "bl_line_object", &revisions); + + char* itemType = NULL; + AOM_ask_value_string(revisions, "object_type", &itemType); + + + string propertyNames = typePropertyType[itemType]; + + if (propertyNames.c_str() != NULL) + { + //ȡ + const char* constName = propertyNames.c_str(); + char* name = new char[2048];//㹻 + strcpy(name, constName); + if (strstr(name, ",") != NULL) + { + //,в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(name, ",", valueChar, &valueCount); + for (int k = 0; k < valueCount; k++) + { + if (strstr(valueChar[k], "=") != NULL) + { + //-в֡ + int valueNum = 0; + char** values = new char* [64]; + //ַָ + split(valueChar[k], "=", values, &valueNum); + + if (strcmp(values[1], "FACTORY") == 0) + { + //printf("values[0]:%s\n", values[0]); + //TCGetPropertyValue(attachments[i], "Revision", values[0], &factoryValues); + AOM_UIF_ask_localized_value_strings(revisions, values[0], "zh_CN", &factoryNum, &factoryValues, &localization_status, &master); + //AOM_ask_value_strings(revisions, values[0], &factoryNum, &factoryValues); + } + } + } + } + else + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(name, "=", valueChar, &valueCount); + if (strcmp(valueChar[1], "FACTORY") == 0) + { + //printf("valueChar[0]:%s\n", valueChar[0]); + AOM_UIF_ask_localized_value_strings(revisions, valueChar[0], "zh_CN", &factoryNum, &factoryValues, &localization_status, &master); + //AOM_UIF_ask_values(revisions, valueChar[0], &factoryNum, &factoryValues); + } + } + } + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + + printf("factoryNum:%d\n", factoryNum); + if (factoryNum > 0) + { + for (int j = 0; j < factoryNum; j++) + { + if (factoryValues[j] == NULL || strcmp(factoryValues[j], "") == 0) + { + continue; + } + printf("factoryValues[j]:%s\n", factoryValues[j]); + getBomLineProperty(topLine, BomLine, typePropertyType, factoryValues[j], date, parameters); + } + } +} + +void getBomLineProperty(tag_t topLine, tag_t BomLine, map typePropertyType, char* bomBaseNum, char* date, char parameters[100000]) +{ + //char parameters[100000] = "";//д뵽ļֵ + //bool isStart = true; + int count = 0; + tag_t* children_line = NULLTAG; + + BOM_line_ask_all_child_lines(topLine, &count, &children_line); + + printf("count:%d\n", count); + for (int i = 0; i < count; i++) + { + //AOM_ask_value_string(children_line[i], "fnd0bl_line_object_type", &itemType); + + + char* itemType = NULL; + AOM_ask_value_string(children_line[i], "bl_item_object_type", &itemType); + + char* puid = NULL; + //ȡPUID + ITK__convert_tag_to_uid(children_line[i], &puid); + string revisionType = itemType; + string typeRev = revisionType + "Revision"; + printf("object_type%s\n", typeRev.c_str()); + //˵ǰ汾Ķ + string propertyNames = typePropertyType[typeRev]; + //printf("propertyNames%s\n", propertyNames.c_str()); + if (!propertyNames.empty() && propertyNames.length() > 0) + { + printf("propertyNames%s\n", propertyNames.c_str()); + if (isSendBomStart) + { + strcat(parameters, "{"); + isSendBomStart = false; + } + else + { + strcat(parameters, ",{"); + } + + const char* constName = propertyNames.c_str(); + char* name = new char[2048];//㹻 + strcpy(name, constName); + + if (strstr(name, ",") != NULL) + { + //,в֡ + printf(",в֡\n"); + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(name, ",", valueChar, &valueCount); + for (int k = 0; k < valueCount; k++) + { + if (strstr(valueChar[k], "=") != NULL) + { + //-в֡ + int valueNum = 0; + char** values = new char* [64]; + //ַָ + split(valueChar[k], "=", values, &valueNum); + + strcat(parameters, "\""); + strcat(parameters, values[1] == NULL ? "" : values[1]); + strcat(parameters, "\""); + strcat(parameters, ":"); + + char* item_rev_value = NULL; + //printf("values[0]%s\n", values[0]); + TCGetPropertyValue(children_line[i], "BOMLine", values[0], &item_rev_value); + //printf("item_rev_value%s\n", item_rev_value); + if (strcmp(values[1], "INPUTTIME") == 0) + { + item_rev_value = date; + } + if (strcmp(values[1], "PARENTID") == 0) + { + TCGetPropertyValue(topLine, "BOMLine", "rev.item_id", &item_rev_value); + } + if (strcmp(values[1], "FACTORY") == 0) + { + item_rev_value = bomBaseNum; + } + + if (strcmp(item_rev_value, "/") == 0) + { + item_rev_value = ""; + } + strcat(parameters, "\""); + strcat(parameters, item_rev_value == NULL ? "" : item_rev_value); + strcat(parameters, "\""); + if (k < valueCount - 1) + { + strcat(parameters, ","); + } + //printf("ַ%s\n", parameters); + + DOFREE(item_rev_value); + } + } + } + else + { + //-в֡ + printf("-в֡\n"); + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(name, "=", valueChar, &valueCount); + + strcat(parameters, "\""); + strcat(parameters, valueChar[1] == NULL ? "" : valueChar[1]); + strcat(parameters, "\""); + strcat(parameters, ":"); + + char* item_rev_value = NULL; + TCGetPropertyValue(children_line[i], "BOMLine", valueChar[0], &item_rev_value); + if (strcmp(valueChar[1], "INPUTTIME") == 0) + { + item_rev_value = date; + } + if (strcmp(valueChar[1], "PARENTID") == 0) + { + TCGetPropertyValue(topLine, "BOMLine", "rev.item_id", &item_rev_value); + } + if (strcmp(valueChar[1], "FACTORY") == 0) + { + item_rev_value = bomBaseNum; + } + + if (strcmp(item_rev_value, "/") == 0) + { + item_rev_value = ""; + } + strcat(parameters, "\""); + strcat(parameters, item_rev_value == NULL ? "" : item_rev_value); + strcat(parameters, "\""); + + //printf("ַ%s\n", parameters); + + DOFREE(item_rev_value); + } + strcat(parameters, "}"); + + DOFREE(constName); + } + + + DOFREE(replaceProject); + DOFREE(itemType); + DOFREE(puid); + + printf("parameters:%s\n", parameters); + getBomLineProperty(children_line[i], BomLine, typePropertyType, bomBaseNum, date, parameters); + } + + DOFREE(children_line); +} + + +map getClassAttrMap(map> classMap, char* classId) { + map attrMap; + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + return attrMap; +} + +void getItemClass(int status, char* itemType, tag_t ico_tag, tag_t zi_rev, map attrMap, char* classId, char** classCode) { + printf("-----------------getItemClass------------------------\n"); + if (status) + { + printf("ʾ:мݱʧ\n"); + } + else { + char* field1 = NULL; + char* field2 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0) { + if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field1); + DOFREE(value); + } + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field2)); + } + else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* new_classId = NULL; + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) + { + new_classId = getFirstStr(classId, 2); + } + else + { + new_classId = getFirstStr(classId, 4); + } + tag_t classTag = NULLTAG; + char* id = NULL; + if (new_classId != NULL) { + ITKCALL(ICS_find_class(new_classId, &classTag)); + if (classTag != NULLTAG) + { + ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); + } + } + if (id != NULL) { + DOFREE(id); + } + if (classTag != NULL) { + DOFREE(classTag); + } + if (new_classId != NULL) { + DOFREE(new_classId); + } + } + if (field1 != NULL) { + if (field1 != NULL && field2 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s' and PFIELD02= '%s'", field1, field2); + } + else { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + } + } + else { + if (strcmp("RB3_ZCRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_zclx", &field1)); + } + else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 + || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 + || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 + || strcmp("RB3_GZBJRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + printf("ʾ:field1T==%s\n", field1); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0 + || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_bjlx", &field1)); + } + else if (strcmp("RB3_XZCPRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_cplx2", &field1)); + } + else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field1); + DOFREE(value); + } + } + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + } + if (strcmp("", sql) != 0) { + printf("ʾ:sqlT==%s\n", sql); + if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + //printf("ʾ:Ϸѯ ʧ, %s \n", sql); + char sql2[128] = "\0"; + sprintf(sql2, "select PCLASSCODE,PCLASSNAME from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + printf("ʾ:sql2T==%s\n", sql2); + if (QuerySQLNoInputParam(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) + { + printf("ʾ:Ϸѯ ʧ, %s \n", sql2); + } + } + printf("outputValueCount=%d\n", outputValueCount); + printf("outputColumn=%d\n", outputColumn); + //free(sql); + if (outputValueCount > 0) { + *classCode = outputValue[0][0]; + printf("Ϸ====%s\n", *classCode); + } + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + } + +} + +void getBomLinePropertyNew(tag_t topLine, char** c_sql_values, vector* parameters_vec, map> classMap, map> factoryMap, map unitMap) +{ + printf("ʼȡӼϢ\n"); + tag_t fu_rev = NULLTAG; + AOM_ask_value_tag(topLine, "bl_line_object", &fu_rev); + + tag_t* children_line = NULLTAG; + int count = 0; + + BOM_line_ask_all_child_lines(topLine, &count, &children_line); + if (count > 0) { + int status = ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + char* fu_item_id = NULL; + char* fu_smzqzt = NULL; + char* fu_item_revision_id = NULL; + char* fu_object_name = NULL; + char* fu_object_type = NULL; + char* fu_cph = NULL; + char** fu_scgc = NULL; + int factoryCount = 0; + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_id", &fu_item_id)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_smzqzt", &fu_smzqzt)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_revision_id", &fu_item_revision_id)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "object_name", &fu_object_name)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cph", &fu_cph)); + char* itemType = NULL; + AOM_ask_value_string(fu_rev, "object_type", &itemType); + if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_xzscgc", &factoryCount, &fu_scgc)); + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 + || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_scgc", &factoryCount, &fu_scgc)); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_sygc1", &factoryCount, &fu_scgc)); + } + else { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_scgc1", &factoryCount, &fu_scgc)); + } + ITKCALL(AOM_ask_value_string(fu_rev, "object_type", &fu_object_type)); + + char facttoryNameStr[4000] = "\0"; + char factoryCodeStr[2000] = "\0"; + char organizeNameStr[5000] = "\0"; + char organizeCodeStr[3000] = "\0"; + //д,ʵ(ͬ) + if (status) + { + printf("ʾ:мݱʧ\n"); + } + else { + //֯⴦,ͨݿƥ + + for (int i = 0; i < factoryCount; i++) + { + if (factoryMap.find(fu_scgc[i]) == factoryMap.end()) { + char* factoryCode = NULL; + char* factoryName = NULL; + int factoryColumn = 0, factoryValueCount = 0; + char*** factoryValue = NULL; + char factorySql[128] = "\0"; + sprintf(factorySql, "select PFACTORYCODE,PFACTORYNAME from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", fu_scgc[i]); + printf("ʾ:factorySql==%s\n", factorySql); + if (QuerySQLNoInputParam(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + printf("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + //printf("factoryValueCount=%d\n", factoryValueCount); + //printf("factoryColumn=%d\n", factoryColumn); + if (factoryValueCount > 0) { + factoryCode = factoryValue[0][0]; + factoryName = factoryValue[0][1]; + vector factoryVec; + factoryVec.push_back(factoryCode); + factoryVec.push_back(factoryName); + factoryMap[fu_scgc[i]] = factoryVec; + //printf("֯====%s\n", factoryCode); + //printf("֯====%s\n", factoryName); + if (strcmp(facttoryNameStr, "") != 0) { + strcat(facttoryNameStr, ","); + strcat(factoryCodeStr, ","); + } + if (factoryName != NULL) { + strcat(facttoryNameStr, factoryName); + } + if (factoryCode != NULL) { + strcat(factoryCodeStr, factoryCode); + } + + } + if (factoryValue != NULL) { + DOFREE(factoryValue); + } + if (factoryCode != NULL) { + DOFREE(factoryCode); + } + if (factoryName != NULL) { + DOFREE(factoryName); + } + } + else { + vector factoryVec = factoryMap[fu_scgc[i]]; + if (strcmp(facttoryNameStr, "") != 0) { + strcat(facttoryNameStr, ","); + strcat(factoryCodeStr, ","); + } + strcat(factoryCodeStr, factoryVec[0].c_str()); + strcat(facttoryNameStr, factoryVec[1].c_str()); + + } + + } + char* fu_class_code = NULL; + tag_t fu_ico_tag = NULLTAG; + char* fu_class_id = NULL; + map fuAttrMap; + ICS_ask_classification_object(fu_rev, &fu_ico_tag); + if (fu_ico_tag != NULLTAG) { + ICS_ico_ask_class(fu_ico_tag, &fu_class_id); + printf(">> fu_class_id: %s\n", fu_class_id); + fuAttrMap = getClassAttrMap(classMap, fu_class_id); + } + getItemClass(status, fu_object_type, fu_ico_tag, fu_rev, fuAttrMap, fu_class_id, &fu_class_code); + //֯߼ + char* organizeCode = NULL; + char* organizeName = NULL; + char* organizeFactory = NULL; + char factorySql2[128] = "\0"; + int organizeColumn = 0, organizeValueCount = 0; + char*** organizeValue = NULL; + printf("fu_object_type: %s\n", fu_object_type); + printf("fu_class_code: %s\n", fu_class_code); + printf("fu_item_id: %s\n", fu_item_id); + if (strcmp("RB3_LBJRevision", fu_object_type) == 0) { + sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where CLASSCODE= '%s'", fu_class_code); + printf("ʾ:factorySql2==%s\n", factorySql2); + if (QuerySQLNoInputParam(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + printf("ʾ:֯ѯ ʧ, %s \n", factorySql2); + } + //printf("factoryValueCount=%d\n", organizeValueCount); + //printf("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeFactory = organizeValue[0][0]; + organizeCode = organizeValue[0][1]; + organizeName = organizeValue[0][2]; + printf("֯====%s\n", organizeFactory); + printf("֯2====%s\n", organizeName); + printf("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeFactory != NULL && strcmp("", organizeFactory) != 0 && strcmp("NULL", organizeFactory) != 0) { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0 && strcmp("", organizeName) != 0) { + if (strcmp(organizeNameStr, "") != 0) { + strcat(organizeNameStr, ","); + } + strcat(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0 && strcmp("", organizeCode) != 0) { + if (strcmp(organizeCodeStr, "") != 0) { + strcat(organizeCodeStr, ","); + } + strcat(organizeCodeStr, organizeCode); + } + } + else if (strcmp("RB3_XZCPRevision", fu_object_type) == 0) { + char* field1 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cplx2", &field1)); + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + printf("ʾ:Ϸѯ ʧ, %s \n", sql); + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + else { + //printf("outputValueCount=%d\n", outputValueCount); + //printf("outputColumn=%d\n", outputColumn); + //free(sql); + char* fuClassCode = NULL; + if (outputValueCount > 0) { + fuClassCode = outputValue[0][0]; + //printf("Ϸ====%s\n", fuClassCode); + } + if (strcmp("IN07", fuClassCode) == 0) { + sprintf(factorySql2, "select PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PTYPE= 'RB3_GNZCRevision' and PFIELD01= ''"); + printf("ʾ:factorySql2==%s\n", factorySql2); + if (QuerySQLNoInputParam(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + printf("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + } + //printf("factoryValueCount=%d\n", organizeValueCount); + //printf("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeCode = organizeValue[0][0]; + organizeName = organizeValue[0][1]; + printf("֯2====%s\n", organizeName); + printf("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0) { + strcpy(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0) { + strcpy(organizeCodeStr, organizeCode); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (fuClassCode != NULL) { + DOFREE(fuClassCode); + } + } + if (field1 != NULL) { + DOFREE(field1); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + } + else if (strcmp("RB3_BZJRevision", fu_object_type) == 0) { + char* field1 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + ITKCALL(AOM_UIF_ask_value(fu_rev, "object_name", &field1)); + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + printf("ʾ:Ϸѯ ʧ, %s \n", sql); + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + else { + //printf("outputValueCount=%d\n", outputValueCount); + //printf("outputColumn=%d\n", outputColumn); + //free(sql); + char* fuClassCode = NULL; + if (outputValueCount > 0) { + fuClassCode = outputValue[0][0]; + //printf("Ϸ====%s\n", fuClassCode); + } + if (strcmp("IN07", fuClassCode) == 0) { + sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where CLASSCODE= '%s'", fuClassCode); + printf("ʾ:factorySql2==%s\n", factorySql2); + if (QuerySQLNoInputParam(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + printf("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + } + //printf("factoryValueCount=%d\n", organizeValueCount); + //printf("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeFactory = organizeValue[0][0]; + organizeCode = organizeValue[0][1]; + organizeName = organizeValue[0][2]; + printf("֯====%s\n", organizeFactory); + printf("֯2====%s\n", organizeName); + printf("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeFactory != NULL && strcmp("", organizeFactory) != 0 && strcmp("NULL", organizeFactory) != 0) { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0 && strcmp("", organizeName) != 0) { + if (strcmp(organizeNameStr, "") != 0) { + strcat(organizeNameStr, ","); + } + strcat(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0 && strcmp("", organizeCode) != 0) { + if (strcmp(organizeCodeStr, "") != 0) { + strcat(organizeCodeStr, ","); + } + strcat(organizeCodeStr, organizeCode); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (fuClassCode != NULL) { + DOFREE(fuClassCode); + } + } + if (field1 != NULL) { + DOFREE(field1); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + //if (strcmp("RB3_ZCRevision", fu_object_type) == 0) { + // if (strstr(fu_object_name, "") == NULL) { + // sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PFIELD01= '%s'", fu_object_name); + // printf("ʾ:factorySql2==%s\n", factorySql2); + // if (QuerySQLNoInputParam(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + // { + // printf("ʾ:֯ѯ ʧ, %s \n", factorySql2); + // } + // printf("factoryValueCount=%d\n", organizeValueCount); + // printf("factoryColumn=%d\n", organizeColumn); + // organizeFactory = organizeValue[0][0]; + // organizeCode = organizeValue[0][1]; + // organizeName = organizeValue[0][2]; + // printf("֯====%s\n", organizeFactory); + // printf("֯2====%s\n", organizeName); + // printf("֯2====%s\n", organizeCode); + // if (strcmp("", organizeFactory) != 0 && organizeFactory != NULL && strcmp("NULL", organizeFactory) != 0) { + // strcpy(organizeNameStr, facttoryNameStr); + // strcpy(organizeCodeStr, factoryCodeStr); + // } + // if (organizeName != NULL && strcmp("NULL", organizeName) != 0) { + // if (strcmp(organizeNameStr, "") != 0) { + // strcat(organizeNameStr, ","); + // } + // strcat(organizeNameStr, organizeName); + // } + // if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0) { + // if (strcmp(organizeCodeStr, "") != 0) { + // strcat(organizeCodeStr, ","); + // } + // strcat(organizeCodeStr, organizeCode); + // } + // } + // else { + // strcpy(organizeNameStr, facttoryNameStr); + // strcpy(organizeCodeStr, factoryCodeStr); + + // } + //} + //else if (strcmp("RB3_XZCPRevision", fu_object_type) == 0) { + // char* field1 = NULL; + // int outputColumn = 0, outputValueCount = 0; + // char*** outputValue = NULL; + // //Ϸ⴦,ͨݿƥ + // char sql[1024] = "\0"; + // ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cplx2", &field1)); + // if (field1 != NULL) { + // sprintf(sql, "select PCLASSCODE from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + // } + // if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + // { + // printf("ʾ:Ϸѯ ʧ, %s \n", sql); + // } + // else { + // printf("outputValueCount=%d\n", outputValueCount); + // printf("outputColumn=%d\n", outputColumn); + // //free(sql); + // char* fuClassCode = NULL; + // if (outputValueCount > 0) { + // fuClassCode = outputValue[0][0]; + // printf("Ϸ====%s\n", fuClassCode); + // } + // if (strcmp("IN07", fuClassCode) == 0) { + // sprintf(factorySql2, "select PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PTYPE= 'RB3_GNZCRevision' and PFIELD01= ''"); + // } + // else { + // sprintf(factorySql2, "select PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PTYPE= 'RB3_GNZCRevision' and PFIELD01= 'Ʒ'"); + // } + // printf("ʾ:factorySql2==%s\n", factorySql2); + // if (QuerySQLNoInputParam(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + // { + // printf("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + // } + // printf("factoryValueCount=%d\n", organizeValueCount); + // printf("factoryColumn=%d\n", organizeColumn); + // organizeCode = organizeValue[0][0]; + // organizeName = organizeValue[0][1]; + // printf("֯2====%s\n", organizeName); + // printf("֯2====%s\n", organizeCode); + // if (organizeName != NULL && strcmp("NULL", organizeName) != 0) { + // strcpy(organizeNameStr, organizeName); + // } + // if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0) { + // strcpy(organizeCodeStr, organizeCode); + // } + // if (fuClassCode != NULL) { + // DOFREE(fuClassCode); + // } + // } + // if (field1 != NULL) { + // DOFREE(field1); + // } + // if (outputValue != NULL) { + // DOFREE(outputValue); + // } + //} + //else if (strcmp("RB3_GNZCRevision", fu_object_type) == 0) { + // sprintf(factorySql2, "select PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PTYPE= 'RB3_GNZCRevision'"); + // printf("ʾ:factorySql2==%s\n", factorySql2); + + // if (QuerySQLNoInputParam(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + // { + // printf("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + // } + // printf("factoryValueCount=%d\n", organizeValueCount); + // printf("factoryColumn=%d\n", organizeColumn); + // organizeCode = organizeValue[0][0]; + // organizeName = organizeValue[0][1]; + // printf("֯2====%s\n", organizeName); + // printf("֯2====%s\n", organizeCode); + // if (organizeName != NULL && strcmp("NULL", organizeName) != 0) { + // strcpy(organizeNameStr, organizeName); + // } + // if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0) { + // strcpy(organizeCodeStr, organizeCode); + // } + //} + //else { + // strcpy(organizeNameStr, facttoryNameStr); + // strcpy(organizeCodeStr, factoryCodeStr); + + //} + if (organizeCode != NULL) { + DOFREE(organizeCode); + } + if (organizeName != NULL) { + DOFREE(organizeName); + } + if (organizeFactory != NULL) { + DOFREE(organizeFactory); + } + if (organizeValue != NULL) { + DOFREE(organizeValue); + } + if (fu_class_code != NULL) { + DOFREE(fu_class_code); + } + if (fu_class_id != NULL) { + DOFREE(fu_class_id); + } + } + printf("count:%d\n", count); + // ʼԤ󳤶 + size_t buffer_size = 200000; // ʼСɸʵ + char* parameters = static_cast(malloc(buffer_size)); + + parameters[0] = '\0'; // ȷַԿַʼ + strcat(parameters, "{"); + + //AOM_ask_value_string(children_line[i], "fnd0bl_line_object_type", &itemType); + strcat(parameters, "\"parentPartCode\":\""); + strcat(parameters, fu_item_id == NULL ? "" : fu_item_id); + strcat(parameters, "\","); + strcat(parameters, "\"lifeCycleStages\":\""); + strcat(parameters, fu_smzqzt == NULL ? "" : fu_smzqzt); + strcat(parameters, "\","); + strcat(parameters, "\"version\":\""); + strcat(parameters, fu_item_revision_id == NULL ? "" : fu_item_revision_id); + strcat(parameters, "\","); + strcat(parameters, "\"componentType\":\""); + strcat(parameters, fu_object_name == NULL ? "" : fu_object_name); + strcat(parameters, "\","); + strcat(parameters, "\"bomProductNumber1\":\""); + strcat(parameters, fu_cph == NULL ? "" : fu_cph); + strcat(parameters, "\","); + strcat(parameters, "\"usingOrgName\":\""); + strcat(parameters, organizeNameStr == NULL ? "" : organizeNameStr); + strcat(parameters, "\","); + strcat(parameters, "\"usingOrgCode\":\""); + strcat(parameters, organizeCodeStr == NULL ? "" : organizeCodeStr); + strcat(parameters, "\","); + strcat(parameters, "\"bomDetail\":["); + for (int i = 0; i < count; i++) + { + tag_t zi_rev = NULLTAG; + AOM_ask_value_tag(children_line[i], "bl_line_object", &zi_rev); + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(zi_rev, &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + printf(">> classId: %s\n", classId); + attrMap = getClassAttrMap(classMap, classId); + } + char* itemType = NULL; + AOM_ask_value_string(zi_rev, "object_type", &itemType); + printf("object_type: %s\n", itemType); + char* zi_item_id = NULL; + char* zi_smzqzt = NULL; + char* zi_item_revision_id = NULL; + char* zi_object_name = NULL; + char* zi_cph = NULL; + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_id", &zi_item_id)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_smzqzt", &zi_smzqzt)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_revision_id", &zi_item_revision_id)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &zi_object_name)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_cph", &zi_cph)); + char* zi_uom = NULL; + char* zi_quantity = NULL; + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_uom", &zi_uom)); + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_quantity", &zi_quantity)); + strcat(parameters, "{"); + strcat(parameters, "\"componentCode\":\""); + strcat(parameters, zi_item_id == NULL ? "" : zi_item_id); + strcat(parameters, "\","); + strcat(parameters, "\"theLifecycle\":\""); + strcat(parameters, zi_smzqzt == NULL ? "" : zi_smzqzt); + strcat(parameters, "\","); + strcat(parameters, "\"bomObjectVersion\":\""); + strcat(parameters, zi_item_revision_id == NULL ? "" : zi_item_revision_id); + strcat(parameters, "\","); + strcat(parameters, "\"bomObjectType\":\""); + strcat(parameters, zi_object_name == NULL ? "" : zi_object_name); + strcat(parameters, "\","); + strcat(parameters, "\"bomProductNumber\":\""); + strcat(parameters, zi_cph == NULL ? "" : zi_cph); + strcat(parameters, "\","); + strcat(parameters, "\"bomQuantity\":"); + strcat(parameters, zi_quantity == NULL ? "" : zi_quantity); + strcat(parameters, ","); + char* classCode = NULL; + getItemClass(status, itemType, ico_tag, zi_rev, attrMap, classId, &classCode); + + //Ӽλת߼ + if (strstr(zi_uom, "ϵ") != NULL) { + strcat(parameters, "\"parentItemBase\":1,"); + } + else { + printf("zi_uom111 = %s \n", zi_uom); + printf("classCode111 = %s \n", classCode); + if (classCode != NULL) { + if (strcmp("IN07", classCode) == 0 && strstr("L()", zi_uom) != NULL) + { + zi_uom = "WL()"; + strcat(parameters, "\"parentItemBase\":10000,"); + } + else if ((strcmp("IN01", classCode) == 0 || strcmp("IN56", classCode) == 0 || strcmp("IN59", classCode) == 0) && strstr("GM()", zi_uom) != NULL) + { + zi_uom = "T()"; + strcat(parameters, "\"parentItemBase\":1000000,"); + } + else if (strcmp("IN12", classCode) == 0 && strstr("GM()", zi_uom) != NULL) + { + zi_uom = "KG(ǧ)"; + strcat(parameters, "\"parentItemBase\":1000,"); + } + else { + strcat(parameters, "\"parentItemBase\":1,"); + } + } + else { + strcat(parameters, "\"parentItemBase\":1,"); + } + } + strcat(parameters, "\"bomUnit\":\""); + if (unitMap.find(zi_uom) != unitMap.end()) { + strcat(parameters, unitMap[zi_uom].c_str()); + } + else { + strcat(parameters, zi_uom); + } + strcat(parameters, "\""); + strcat(parameters, "}"); + //printf("parameters%d:%s\n", i,parameters); + if (i < count - 1) { + strcat(parameters, ","); + } + if (zi_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (zi_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (zi_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (zi_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (zi_cph != NULL) + { + DOFREE(fu_cph); + } + if (zi_uom != NULL) + { + DOFREE(zi_uom); + } + if (zi_quantity != NULL) + { + DOFREE(zi_quantity); + } + if (classCode != NULL) + { + DOFREE(classCode); + } + if (itemType != NULL) { + DOFREE(itemType); + } + } + if (fu_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (fu_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (fu_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (fu_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (fu_cph != NULL) + { + DOFREE(fu_cph); + } + if (fu_scgc != NULL) + { + DOFREE(fu_scgc); + } + if (fu_object_type != NULL) + { + DOFREE(fu_object_type); + } + DisConnServer(); + strcat(parameters, "]}"); + parameters_vec->push_back(parameters); + } + for (int i = 0; i < count; i++) + { + int child_count = 0; + tag_t* zi_children_line = NULLTAG; + BOM_line_ask_all_child_lines(children_line[i], &child_count, &zi_children_line); + if (child_count > 0) { + getBomLinePropertyNew(children_line[i], c_sql_values, parameters_vec, classMap, factoryMap, unitMap); + } + } + if (children_line != NULL) + { + DOFREE(children_line); + } + +} + +int RB_SendErpBom_New(EPM_action_message_t msg) +{ + printf("=========================BOM·ERP Start===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + printf("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + return 1; + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + + char errorMessage[100000] = "";//д뵽ļֵ + for (int i = 0; i < attachments_num; i++) + { + char* itemType = NULL; + AOM_ask_value_string(attachments[i], "object_type", &itemType); + + printf("itemType%s\n", itemType); + + //˵ǰ汾Ķ + if (strcmp(itemType, "RB3_ZCRevision") == 0 || strcmp(itemType, "RB3_GNZCRevision") == 0 || strcmp(itemType, "RB3_XZCPRevision") == 0) + { + //ȡ + tag_t top_line = NULLTAG, window = NULLTAG; + BOM_create_window(&window); + //öBOM + BOM_set_window_top_line(window, NULLTAG, attachments[i], NULLTAG, &top_line); + //ȡjsonַ + vector parameters_vec; + map> classMap; + map> factoryMap; + printf("=========================ȡӼϢ===================\n"); + getBomLinePropertyNew(top_line, c_sql_values, ¶meters_vec, classMap, factoryMap, unitMap) + + DOFREE(itemType); + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "{\"data\":["); + for (int i = 0; i < parameters_vec.size(); i++) + { + strcat(parameters, parameters_vec[i].c_str()); + if (i < parameters_vec.size() - 1) { + strcat(parameters, ","); + } + } + strcat(parameters, "],\"control\":{\"keydata\":null,\"ifid\": null,\"ifno\":\"JDE_MDM_BOM_01\",\"suser\": null,\"sysid\": null}}"); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + printf("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + ////strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@BOM"); + //strcat(cmd,handler_name); + //printf("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + strResult = strResult.substr(0, iSize - 1); + cout << strResult << endl; + if (strstr(strResult.c_str(), "\"code\":200") == NULL) + { + printf("·ɹ\n"); + strcat(errorMessage, strResult.c_str()); + + } + } + DOFREE(itemType); + } + } + + MEM_free(attachments); + MEM_free(c_sql_values); + if (ifail == 1) + { + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + } + printf("=========================BOM·ERP End===================\n"); + return ifail; +} + +void getGYLXBomLinePropertyNew(tag_t topLine, char** c_sql_values, vector* parameters_vec, map unitMap, map> classMap, map workCenterMap) +{ + + map> ziVecMap; + tag_t* children_line = NULLTAG; + int count = 0; + map> factoryMap; + ITKCALL(BOM_line_ask_all_child_lines(topLine, &count, &children_line)); + if (count > 0) { + int status = ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + //ȡ·߹Ŀ + tag_t fu_rev = NULLTAG; + ITKCALL(AOM_ask_value_tag(topLine, "bl_line_object", &fu_rev)); + tag_t* wl_items = NULLTAG; + int wl_count = 0; + ITKCALL(AOM_ask_value_tags(fu_rev, "IMAN_METarget", &wl_count, &wl_items)); + char* fu_item_id = NULL; + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_id", &fu_item_id)); + int valueCount = 0; + char** valueChar = new char* [64]; + if (strstr(fu_item_id, "_") != NULL) { + //-в֡ + + //ַָ + split(fu_item_id, "_", valueChar, &valueCount); + } + char* describe1 = NULL;//rb3_ms + char* partNumber = NULL;//rb3_jh + char* productId = NULL;//rb3_cph + char* assemblyType = NULL;//rb3_zclx + char* lifecycleState = NULL;//rb3_smzqzt + char* item_type = NULL; + if (wl_count > 0) { + tag_t wl_item = wl_items[0]; + ITKCALL(AOM_ask_value_string(wl_item, "object_type", &item_type)); + printf("item_type = %s \n", item_type); + if (strcmp("RB3_ZCRevision", item_type) == 0) { + ITKCALL(AOM_UIF_ask_value(wl_item, "rb3_ms", &describe1)); + ITKCALL(AOM_UIF_ask_value(wl_item, "rb3_cph", &productId)); + ITKCALL(AOM_UIF_ask_value(wl_item, "rb3_zclx", &assemblyType)); + ITKCALL(AOM_UIF_ask_value(wl_item, "rb3_smzqzt", &lifecycleState)); + } + else if (strcmp("RB3_LBJRevision", item_type) == 0) { + ITKCALL(AOM_UIF_ask_value(wl_item, "rb3_jh", &partNumber)); + + } + } + printf("count:%d\n", count); + for (int i = 0; i < count; i++) + { + char* wlbm = NULL;//bl_MEOPRevision_rb3_wlbm materialCode ϱ + char* jgbz = NULL;//bl_MEOPRevision_rb3_jgbz processingSteps ӹ + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_MEOPRevision_rb3_wlbm", &wlbm)); + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_MEOPRevision_rb3_jgbz", &jgbz)); + if (wlbm == NULL || strcmp("", wlbm) == 0 || jgbz == NULL || strcmp("", jgbz) == 0) { + if (wlbm != NULL) { + DOFREE(wlbm); + } + if (jgbz != NULL) { + DOFREE(jgbz); + } + continue; + } + char* jgbz_rel = NULL; + ITKCALL(AOM_ask_value_string(children_line[i], "bl_MEOPRevision_rb3_jgbz", &jgbz_rel)); + char processRouteCode[64] = "\0"; + char processRouteName[64] = "\0"; + strcpy(processRouteCode, wlbm); + strcat(processRouteCode, jgbz_rel); + strcpy(processRouteName, wlbm); + strcat(processRouteName, jgbz); + + if (ziVecMap.find(processRouteCode) == ziVecMap.end()) { + vector ziVec; + ziVec.push_back(children_line[i]); + ziVecMap.insert(std::make_pair(processRouteCode, ziVec)); + } + else { + + vector ziVec = ziVecMap[processRouteCode]; + //printf("parameters_mapֵ \n"); + ziVec.push_back(children_line[i]); + // ɾԪ + ziVecMap.erase(processRouteCode); + ziVecMap.insert(std::make_pair(processRouteCode, ziVec)); + } + } + for (std::map>::iterator it = ziVecMap.begin(); it != ziVecMap.end(); ++it) + { + string key = it->first; + vector ziVec = it->second; + char fu_params[10000] = "\0"; + for (int i = 0; i < ziVec.size(); i++) + { + tag_t zi_tag = ziVec[i]; + char* wlbm = NULL;//bl_MEOPRevision_rb3_wlbm materialCode ϱ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_wlbm", &wlbm)); + char* jgbz = NULL;//bl_MEOPRevision_rb3_jgbz processingSteps ӹ + char* jgbz_rel = NULL; + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_jgbz", &jgbz)); + ITKCALL(AOM_ask_value_string(zi_tag, "bl_MEOPRevision_rb3_jgbz", &jgbz_rel)); + char* sfww = NULL;//bl_MEOPRevision_rb3_sfww whetherOutsource Ƿί + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_sfww", &sfww)); + char* sfbg = NULL;//bl_MEOPRevision_rb3_sfbg whetherReportWork Ƿ񱨹 + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_sfbg", &sfbg)); + char* bzgs1 = NULL;//bl_MEOPRevision_rb3_bzgs1 standardWorkingHours ׼ʱ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_bzgs1", &bzgs1)); + char bzgs_str[64] = "\0"; + if (bzgs1 != NULL && strcmp(bzgs1, "") != 0 && strcmp(bzgs1, " ") != 0) { + double bzgs_d = std::stod(bzgs1); + //ITKCALL(AOM_ask_value_double(zi_tag, "bl_MEOPRevision_rb3_bzgs1", &bzgs1)); + bzgs_d = round(bzgs_d * 100) / 100; + + //long lValue = static_cast(bzgs_d); // תΪlong + if (bzgs_d > 0) { + sprintf(bzgs_str, "%.2f", bzgs_d); + } + else { + sprintf(bzgs_str, "%0.2f", bzgs_d); + } + printf("bzgs_str: %s\n", bzgs_str); + } + char* bzgsdw = NULL;//bl_MEOPRevision_rb3_bzgsdw standardWorkingHoursUnit ׼ʱλ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_bzgsdw", &bzgsdw)); + char* sfjy = NULL;//bl_MEOPRevision_rb3_sfjy whetherVerify Ƿ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_sfjy", &sfjy)); + char* gzzx = NULL;//bl_MEOPRevision_rb3_gzzx workCenter + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_gzzx", &gzzx)); + char* sepuence_no = NULL;//bl_sepuence_no findNumber ұ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_sequence_no", &sepuence_no)); + char* quantity = NULL;//bl_quantity quantity + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_quantity", &quantity)); + char* uom = NULL;//bl_uom unitMeasurement λ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_uom", &uom)); + + + int factoryCount = 0; + char* scgc = NULL;//bl_MEOPRevision_rb3_scgc unitMeasurement λ + ITKCALL(AOM_UIF_ask_value(zi_tag, "bl_MEOPRevision_rb3_scgc", &scgc)); + if (strstr(scgc, ",") != NULL) { + removeChar(scgc, ','); + } + char* gxh = NULL;//RB3_GXH processNumber ׼ + ITKCALL(AOM_UIF_ask_value(zi_tag, "RB3_GXH", &gxh)); + //printf("jgbz = %s\n", jgbz); + //printf("jgbz_rel = %s\n", jgbz_rel); + //printf("sfww = %s\n", sfww); + //printf("sfbg = %s\n", sfbg); + //printf("bzgs1 = %s\n", bzgs1); + //printf("bzgsdw = %s\n", bzgsdw); + //printf("sfjy = %s\n", sfjy); + //printf("gzzx = %s\n", gzzx); + //printf("sepuence_no = %s\n", sepuence_no); + //printf("quantity = %s\n", quantity); + //printf("uom = %s\n", uom); + //printf("scgc = %s\n", scgc); + //printf("gxh = %s\n", gxh); + char* newStr = NULL; + if (strcmp("", scgc) != 0) { + newStr = removeSpaces(scgc); + } + printf("newStr = %s\n", newStr); + tag_t zi_rev = NULLTAG; + ITKCALL(AOM_ask_value_tag(zi_tag, "bl_line_object", &zi_rev)); + char* item_id = NULL;//item_id componentId ID + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_id", &item_id)); + char* object_name = NULL;//object_name componentName + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &object_name)); + //ƶӦid map洢 + tag_t ico_tag = NULLTAG; + char* cplb_disValue = NULL; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(zi_rev, &ico_tag); + if (ico_tag != NULLTAG) { + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + + if (attrMap.find("Ʒ") != attrMap.end()) + { + char* cplb = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &cplb); + if (cplb != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(cplb, id, &cplb_disValue); + DOFREE(cplb); + } + } + } + char* rev_id = NULL;//object_name version 汾 + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_revision_id", &rev_id)); + + char processRouteCode[64] = "\0"; + char processRouteName[64] = "\0"; + strcpy(processRouteCode, wlbm); + strcat(processRouteCode, jgbz_rel); + strcpy(processRouteName, wlbm); + strcat(processRouteName, jgbz); + //printf("processRouteCode =%s\n", processRouteCode); + //printf("processRouteName =%s\n", processRouteName); + char* factoryCode = NULL; + char* factoryName = NULL; + string factoryCodeStr = ""; + string facttoryNameStr = ""; + if (newStr != NULL) { + if (factoryMap.find(newStr) != factoryMap.end()) { + vector factoryVec = factoryMap[newStr]; + factoryCodeStr = factoryVec[0]; + facttoryNameStr = factoryVec[1]; + } + else { + if (status) + { + printf("ʾ:мݱʧ\n"); + } + else { + //֯⴦,ͨݿƥ + + int factoryColumn = 0, factoryValueCount = 0; + char*** factoryValue = NULL; + char factorySql[128] = "\0"; + sprintf(factorySql, "select PFACTORYCODE,PFACTORYNAME from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", newStr); + printf("ʾ:factorySql==%s\n", factorySql); + if (QuerySQLNoInputParam(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + printf("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + printf("factoryValueCount=%d\n", factoryValueCount); + printf("factoryColumn=%d\n", factoryColumn); + if (factoryValueCount > 0) { + factoryCode = factoryValue[0][0]; + factoryName = factoryValue[0][1]; + vector factoryVec; + factoryVec.push_back(factoryCode); + factoryVec.push_back(factoryName); + factoryMap[newStr] = factoryVec; + printf("֯====%s\n", factoryCode); + printf("֯====%s\n", factoryName); + } + if (factoryValue != NULL) { + DOFREE(factoryValue); + } + + } + } + } + if (strcmp("", fu_params) == 0) { + strcat(fu_params, "{\"processRouteCode\":\""); + strcat(fu_params, processRouteCode); + strcat(fu_params, "\","); + strcat(fu_params, "\"processRouteName\":\""); + strcat(fu_params, processRouteName); + strcat(fu_params, "\","); + strcat(fu_params, "\"productionFactoryCode\":\""); + if (factoryCode != NULL) { + strcat(fu_params, factoryCode); + } + else { + strcat(fu_params, factoryCodeStr.c_str()); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"processingSteps\":\""); + strcat(fu_params, jgbz); + strcat(fu_params, "\","); + strcat(fu_params, "\"productionFactoryName\":\""); + if (factoryName != NULL) { + strcat(fu_params, factoryName); + } + else { + strcat(fu_params, facttoryNameStr.c_str()); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"materialCode\":\""); + strcat(fu_params, wlbm); + strcat(fu_params, "\","); + strcat(fu_params, "\"version\":\""); + if (valueCount > 0) { + strcat(fu_params, valueChar[1]); + strcat(fu_params, rev_id); + } + else { + strcat(fu_params, rev_id); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"standardWorkingHoursUnit\":\""); + strcat(fu_params, bzgsdw); + strcat(fu_params, "\","); + strcat(fu_params, "\"processDetailed\":\ ["); + } + strcat(fu_params, "{"); + strcat(fu_params, "\"componentId\":\""); + strcat(fu_params, item_id); + strcat(fu_params, "\","); + strcat(fu_params, "\"describe1\":\""); + if (describe1 != NULL) { + strcat(fu_params, describe1); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"processNumber\":\""); + strcat(fu_params, gxh); + strcat(fu_params, "\","); + strcat(fu_params, "\"findNumber\":\""); + strcat(fu_params, sepuence_no); + strcat(fu_params, "\","); + strcat(fu_params, "\"componentName\":\""); + //if (cplb_disValue != NULL) { + // strcat(fu_params, cplb_disValue); + // strcat(fu_params, "-"); + //} + strcat(fu_params, object_name); + strcat(fu_params, "\","); + strcat(fu_params, "\"whetherOutsource\":\""); + strcat(fu_params, sfww); + strcat(fu_params, "\","); + strcat(fu_params, "\"whetherReportWork\":\""); + strcat(fu_params, sfbg); + strcat(fu_params, "\","); + strcat(fu_params, "\"standardWorkingHours\":\""); + strcat(fu_params, bzgs_str); + strcat(fu_params, "\","); + strcat(fu_params, "\"whetherVerify\":\""); + strcat(fu_params, sfjy); + strcat(fu_params, "\","); + strcat(fu_params, "\"workCenter\":\""); + if (workCenterMap.find(gzzx) != workCenterMap.end()) { + strcat(fu_params, workCenterMap[gzzx].c_str()); + } + else { + strcat(fu_params, gzzx); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"unitMeasurement\":\""); + if (unitMap.find(uom) != unitMap.end()) { + strcat(fu_params, unitMap[uom].c_str()); + } + else { + strcat(fu_params, uom); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"quantity\":\""); + strcat(fu_params, quantity); + strcat(fu_params, "\","); + strcat(fu_params, "\"partNumber\":\""); + if (partNumber != NULL) { + strcat(fu_params, partNumber); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"productId\":\""); + if (productId != NULL) { + strcat(fu_params, productId); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"assemblyType\":\""); + if (assemblyType != NULL) { + strcat(fu_params, assemblyType); + } + strcat(fu_params, "\","); + strcat(fu_params, "\"lifecycleState\":\""); + if (lifecycleState != NULL) { + strcat(fu_params, lifecycleState); + } + strcat(fu_params, "\"}"); + if (i < ziVec.size() - 1) { + strcat(fu_params, ","); + } + if (factoryCode != NULL) { + DOFREE(factoryCode); + } + if (factoryName != NULL) { + DOFREE(factoryName); + } + if (zi_tag != NULL) { + DOFREE(zi_tag); + } + if (zi_rev != NULL) { + DOFREE(zi_rev); + } + if (scgc != NULL) { + DOFREE(scgc); + } + if (gxh != NULL) { + DOFREE(gxh); + } + if (object_name != NULL) { + DOFREE(object_name); + } + if (rev_id != NULL) { + DOFREE(rev_id); + } + if (jgbz != NULL) { + DOFREE(jgbz); + } + if (jgbz_rel != NULL) { + DOFREE(jgbz_rel); + } + if (sfww != NULL) { + DOFREE(sfww); + } + if (sfbg != NULL) { + DOFREE(sfbg); + } + if (bzgs1 != NULL) { + DOFREE(bzgs1); + } + if (bzgsdw != NULL) { + DOFREE(bzgsdw); + } + if (sfjy != NULL) { + DOFREE(sfjy); + } + if (gzzx != NULL) { + DOFREE(gzzx); + } + if (sepuence_no != NULL) { + DOFREE(sepuence_no); + } + if (quantity != NULL) { + DOFREE(quantity); + } + if (uom != NULL) { + DOFREE(uom); + } + if (classId != NULL) { + DOFREE(classId); + } + if (cplb_disValue != NULL) { + DOFREE(cplb_disValue); + } + } + strcat(fu_params, "]}"); + parameters_vec->push_back(fu_params); + + } + if (fu_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (describe1 != NULL) { + DOFREE(describe1); + } + if (partNumber != NULL) { + DOFREE(partNumber); + } + if (productId != NULL) { + DOFREE(productId); + } + if (assemblyType != NULL) { + DOFREE(assemblyType); + } + if (lifecycleState != NULL) { + DOFREE(lifecycleState); + } + DisConnServer(); + } + if (children_line != NULL) + { + DOFREE(children_line); + } + factoryMap.clear(); + +} + +int RB_Send_MDM_GYLX_New(EPM_action_message_t msg) +{ + printf("=========================··mdm Start===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + printf("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + return 1; + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int workCenter_pref_cnt = 0; + char** workCenter_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB3_GYLX_workCenter", &workCenter_pref_cnt, &workCenter_pref_vals); + map workCenterMap; + for (int i = 0; i < workCenter_pref_cnt; i++) + { + if (strstr(workCenter_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(workCenter_pref_vals[i], "=", valueChar, &valueCount); + workCenterMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + map> classMap; + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + + for (int i = 0; i < attachments_num; i++) + { + char* itemType = NULL; + AOM_ask_value_string(attachments[i], "object_type", &itemType); + + printf("itemType%s Start===================\n", itemType); + + //˵ǰ汾Ķ + if (strcmp(itemType, "MEProcessRevision") != 0) + { + DOFREE(itemType); + continue; + } + + //ȡ + tag_t top_line = NULLTAG, window = NULLTAG; + BOM_create_window(&window); + //öBOM + BOM_set_window_top_line(window, NULLTAG, attachments[i], NULLTAG, &top_line); + //ȡjsonַ + vector parameters_vec; + getGYLXBomLinePropertyNew(top_line, c_sql_values, ¶meters_vec, unitMap, classMap, workCenterMap); + + + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "{\"data\":["); + for (int i = 0; i < parameters_vec.size(); i++) + { + strcat(parameters, parameters_vec[i].c_str()); + if (i < parameters_vec.size() - 1) { + strcat(parameters, ","); + } + } + strcat(parameters, "],\"control\":{\"keydata\":null,\"ifid\": null,\"ifno\":\"TC_to_MDM_GYLX\",\"suser\": null,\"sysid\": null}}"); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + printf("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + ////strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@GYLX"); + //strcat(cmd,handler_name); + //printf("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + strResult = strResult.substr(0, iSize - 1); + cout << strResult << endl; + if (strstr(strResult.c_str(), "\"code\":200") == NULL) + { + printf("·ɹ\n"); + + } + } + MEM_free(itemType); + } + MEM_free(attachments); + MEM_free(c_sql_values); + printf("=========================··mdm End===================\n"); + return ifail; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_SendErpBom_Rule.cxx b/CONNOR_ITK/RB_SendErpBom_Rule.cxx new file mode 100644 index 0000000..8eaca7f --- /dev/null +++ b/CONNOR_ITK/RB_SendErpBom_Rule.cxx @@ -0,0 +1,1267 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" +#include "OracleDB.h" + + +map getClassAttrMapRule(map> classMap, char* classId) { + map attrMap; + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + return attrMap; +} +void getItemClassRule(char** c_sql_values, char* itemType, tag_t ico_tag, tag_t zi_rev, map attrMap, char* classId, char** classCode,string& errMsg,char* itemId1) { + WriteLog("-----------------getItemClass------------------------\n"); + + char* field1 = NULL; + char* field2 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0) { + if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field1); + DOFREE(value); + } + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field2)); + } + else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* new_classId = NULL; + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) + { + new_classId = getFirstStr(classId, 2); + } + else + { + new_classId = getFirstStr(classId, 4); + } + tag_t classTag = NULLTAG; + char* id = NULL; + if (new_classId != NULL) { + ITKCALL(ICS_find_class(new_classId, &classTag)); + if (classTag != NULLTAG) + { + ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); + } + } + if (id != NULL) { + DOFREE(id); + } + if (classTag != NULL) { + DOFREE(classTag); + } + if (new_classId != NULL) { + DOFREE(new_classId); + } + } + if (field1 != NULL) { + if (field1 != NULL && field2 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s' and PFIELD02= '%s'", field1, field2); + } + else { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + } + } + else { + if (strcmp("RB3_ZCRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_zclx", &field1)); + } + else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 + || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 + || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 + || strcmp("RB3_GZBJRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + WriteLog("ʾ:field1T==%s\n", field1); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0 + || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_bjlx", &field1)); + } + else if (strcmp("RB3_XZCPRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_cplx2", &field1)); + } + else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field1); + DOFREE(value); + } + } + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + + //sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + } + if (strcmp("", sql) != 0) { + WriteLog("ʾ:sqlT==%s\n", sql); + WriteLog("ʾ:sqlT==%s\n", sql); + // ʼ OCILIB + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + if (db.executeQuery(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + if (field1 != NULL) { + char sql2[128] = "\0"; + sprintf(sql2, "select PCLASSCODE,PCLASSNAME from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + WriteLog("ʾ:sql2T==%s\n", sql2); + if (db.executeQuery(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql2); + } + } + + } + + } + db.disconnect(); + WriteLog("outputValueCount=%d\n", outputValueCount); + WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + if (outputValueCount > 0) { + *classCode = outputValue[0][0]; + WriteLog("Ϸ====%s\n", *classCode); + } + else { + + errMsg.append(itemId1); + errMsg.append("Ϸѯʧ,PLM_ERP_FACTORY_TABLE"); + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + return; + + } + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + +} + + +void getBomLinePropertyNewRule(tag_t topLine, char** c_sql_values, vector* parameters_vec, map> classMap, map> factoryMap, map unitMap,string& errMsg,char* itemId1) +{ + WriteLog("ʼȡӼϢ\n"); + tag_t fu_rev = NULLTAG; + AOM_ask_value_tag(topLine, "bl_line_object", &fu_rev); + + tag_t* children_line = NULLTAG; + int count = 0; + + BOM_line_ask_all_child_lines(topLine, &count, &children_line); + if (count > 0) { + + char* fu_item_id = NULL; + char* fu_smzqzt = NULL; + char* fu_item_revision_id = NULL; + char* fu_object_name = NULL; + char* fu_object_type = NULL; + char* fu_cph = NULL; + char** fu_scgc = NULL; + int factoryCount = 0; + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_id", &fu_item_id)); + + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_revision_id", &fu_item_revision_id)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "object_name", &fu_object_name)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cph", &fu_cph)); + char* itemType = NULL; + AOM_ask_value_string(fu_rev, "object_type", &itemType); + + + if (strcmp("RB3_GNLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_smzqtz", &fu_smzqzt)); + } + else { + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_smzqzt", &fu_smzqzt)); + } + + + if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_xzscgc", &factoryCount, &fu_scgc)); + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 + || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_scgc", &factoryCount, &fu_scgc)); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_sygc1", &factoryCount, &fu_scgc)); + } + else { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_scgc1", &factoryCount, &fu_scgc)); + } + ITKCALL(AOM_ask_value_string(fu_rev, "object_type", &fu_object_type)); + + WriteLog("111\n"); + char facttoryNameStr[20000] = "\0"; + char factoryCodeStr[20000] = "\0"; + char organizeNameStr[20000] = "\0"; + char organizeCodeStr[30000] = "\0"; + WriteLog("222\n"); + //д,ʵ(ͬ) + //֯⴦,ͨݿƥ + + for (int i = 0; i < factoryCount; i++) + { + if (factoryMap.find(fu_scgc[i]) == factoryMap.end()) { + char* factoryCode = NULL; + char* factoryName = NULL; + int factoryColumn = 0, factoryValueCount = 0; + char*** factoryValue = NULL; + char factorySql[128] = "\0"; + if (fu_scgc[i] == NULL || strcmp(fu_scgc[i], "") == 0 || strcmp(fu_scgc[i], "0") == 0) { + sprintf(factorySql, "select PFACTORYCODE,PFACTORYNAME from PLM_ERP_FACTORY_TABLE where PFACTORY= 'globa100'"); + + } + else { + sprintf(factorySql, "select PFACTORYCODE,PFACTORYNAME from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", fu_scgc[i]); + + } + WriteLog("ʾ:factorySql==%s\n", factorySql); + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + if (db.executeQuery(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + + } + + + + db.disconnect(); + //WriteLog("factoryValueCount=%d\n", factoryValueCount); + //WriteLog("factoryColumn=%d\n", factoryColumn); + if (factoryValueCount > 0) { + factoryCode = factoryValue[0][0]; + factoryName = factoryValue[0][1]; + vector factoryVec; + factoryVec.push_back(factoryCode); + factoryVec.push_back(factoryName); + factoryMap[fu_scgc[i]] = factoryVec; + //WriteLog("֯====%s\n", factoryCode); + //WriteLog("֯====%s\n", factoryName); + if (strcmp(facttoryNameStr, "") != 0) { + strcat(facttoryNameStr, ","); + strcat(factoryCodeStr, ","); + } + if (factoryName != NULL) { + strcat(facttoryNameStr, factoryName); + } + if (factoryCode != NULL) { + strcat(factoryCodeStr, factoryCode); + } + + } + else { + + + errMsg.append(itemId1); + errMsg.append("֯ѯʧ,PLM_ERP_FACTORY_TABLE"); + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + if (factoryValue != NULL) { + DOFREE(factoryValue); + } + if (factoryCode != NULL) { + DOFREE(factoryCode); + } + if (factoryName != NULL) { + DOFREE(factoryName); + } + return; + + } + if (factoryValue != NULL) { + DOFREE(factoryValue); + } + if (factoryCode != NULL) { + DOFREE(factoryCode); + } + if (factoryName != NULL) { + DOFREE(factoryName); + } + } + else { + vector factoryVec = factoryMap[fu_scgc[i]]; + if (strcmp(facttoryNameStr, "") != 0) { + strcat(facttoryNameStr, ","); + strcat(factoryCodeStr, ","); + } + strcat(factoryCodeStr, factoryVec[0].c_str()); + strcat(facttoryNameStr, factoryVec[1].c_str()); + + } + + } + char* fu_class_code = NULL; + tag_t fu_ico_tag = NULLTAG; + char* fu_class_id = NULL; + map fuAttrMap; + ICS_ask_classification_object(fu_rev, &fu_ico_tag); + if (fu_ico_tag != NULLTAG) { + ICS_ico_ask_class(fu_ico_tag, &fu_class_id); + WriteLog(">> fu_class_id: %s\n", fu_class_id); + fuAttrMap = getClassAttrMapRule(classMap, fu_class_id); + } + getItemClassRule(c_sql_values, fu_object_type, fu_ico_tag, fu_rev, fuAttrMap, fu_class_id, &fu_class_code,errMsg,itemId1); + + if (errMsg.size() > 0) { + if (fu_class_code != NULL) { + DOFREE(fu_class_code); + } + if (fu_class_id != NULL) { + DOFREE(fu_class_id); + } + return; + } + + + //֯߼ + char* organizeCode = NULL; + char* organizeName = NULL; + char* organizeFactory = NULL; + char factorySql2[128] = "\0"; + int organizeColumn = 0, organizeValueCount = 0; + char*** organizeValue = NULL; + WriteLog("fu_object_type: %s\n", fu_object_type); + WriteLog("fu_class_code: %s\n", fu_class_code); + WriteLog("fu_item_id: %s\n", fu_item_id); + if (strcmp("RB3_LBJRevision", fu_object_type) == 0) { + sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where CLASSCODE= '%s'", fu_class_code); + WriteLog("ʾ:factorySql2==%s\n", factorySql2); + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + + + if (db.executeQuery(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factorySql2); + } + } + + + + db.disconnect(); + //WriteLog("factoryValueCount=%d\n", organizeValueCount); + //WriteLog("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeFactory = organizeValue[0][0]; + organizeCode = organizeValue[0][1]; + organizeName = organizeValue[0][2]; + WriteLog("֯====%s\n", organizeFactory); + WriteLog("֯2====%s\n", organizeName); + WriteLog("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeFactory != NULL && strcmp("", organizeFactory) != 0 && strcmp("NULL", organizeFactory) != 0) { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0 && strcmp("", organizeName) != 0) { + if (strcmp(organizeNameStr, "") != 0) { + strcat(organizeNameStr, ","); + } + strcat(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0 && strcmp("", organizeCode) != 0) { + if (strcmp(organizeCodeStr, "") != 0) { + strcat(organizeCodeStr, ","); + } + strcat(organizeCodeStr, organizeCode); + } + } + else if (strcmp("RB3_XZCPRevision", fu_object_type) == 0) { + char* field1 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cplx2", &field1)); + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + + if (db.executeQuery(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + else { + //WriteLog("outputValueCount=%d\n", outputValueCount); + //WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + char* fuClassCode = NULL; + if (outputValueCount > 0) { + fuClassCode = outputValue[0][0]; + //WriteLog("Ϸ====%s\n", fuClassCode); + } + if (strcmp("IN07", fuClassCode) == 0) { + sprintf(factorySql2, "select PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PTYPE= 'RB3_GNZCRevision' and PFIELD01= ''"); + WriteLog("ʾ:factorySql2==%s\n", factorySql2); + if (db.executeQuery(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + } + //WriteLog("factoryValueCount=%d\n", organizeValueCount); + //WriteLog("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeCode = organizeValue[0][0]; + organizeName = organizeValue[0][1]; + WriteLog("֯2====%s\n", organizeName); + WriteLog("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0) { + strcpy(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0) { + strcpy(organizeCodeStr, organizeCode); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (fuClassCode != NULL) { + DOFREE(fuClassCode); + } + } + } + + + + db.disconnect(); + + if (field1 != NULL) { + DOFREE(field1); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + } + else if (strcmp("RB3_BZJRevision", fu_object_type) == 0) { + char* field1 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + ITKCALL(AOM_UIF_ask_value(fu_rev, "object_name", &field1)); + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + if (db.executeQuery(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + else { + //WriteLog("outputValueCount=%d\n", outputValueCount); + //WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + char* fuClassCode = NULL; + if (outputValueCount > 0) { + fuClassCode = outputValue[0][0]; + //WriteLog("Ϸ====%s\n", fuClassCode); + } + if (strcmp("IN07", fuClassCode) == 0) { + sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where CLASSCODE= '%s'", fuClassCode); + WriteLog("ʾ:factorySql2==%s\n", factorySql2); + + + if (db.executeQuery(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + } + + + //WriteLog("factoryValueCount=%d\n", organizeValueCount); + //WriteLog("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeFactory = organizeValue[0][0]; + organizeCode = organizeValue[0][1]; + organizeName = organizeValue[0][2]; + WriteLog("֯====%s\n", organizeFactory); + WriteLog("֯2====%s\n", organizeName); + WriteLog("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeFactory != NULL && strcmp("", organizeFactory) != 0 && strcmp("NULL", organizeFactory) != 0) { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0 && strcmp("", organizeName) != 0) { + if (strcmp(organizeNameStr, "") != 0) { + strcat(organizeNameStr, ","); + } + strcat(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0 && strcmp("", organizeCode) != 0) { + if (strcmp(organizeCodeStr, "") != 0) { + strcat(organizeCodeStr, ","); + } + strcat(organizeCodeStr, organizeCode); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (fuClassCode != NULL) { + DOFREE(fuClassCode); + } + } + + } + + + + db.disconnect(); + if (field1 != NULL) { + DOFREE(field1); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + + if (organizeCode != NULL) { + DOFREE(organizeCode); + } + if (organizeName != NULL) { + DOFREE(organizeName); + } + if (organizeFactory != NULL) { + DOFREE(organizeFactory); + } + if (organizeValue != NULL) { + DOFREE(organizeValue); + } + if (fu_class_code != NULL) { + DOFREE(fu_class_code); + } + if (fu_class_id != NULL) { + DOFREE(fu_class_id); + } + DOFREE(facttoryNameStr); + DOFREE(factoryCodeStr); + + WriteLog("count:%d\n", count); + // ʼԤ󳤶 + size_t buffer_size = 150000; // ʼСɸʵ + char* parameters = static_cast(malloc(buffer_size)); + + parameters[0] = '\0'; // ȷַԿַʼ + strcat(parameters, "{"); + + //AOM_ask_value_string(children_line[i], "fnd0bl_line_object_type", &itemType); + strcat(parameters, "\"parentPartCode\":\""); + strcat(parameters, fu_item_id == NULL ? "" : fu_item_id); + strcat(parameters, "\","); + strcat(parameters, "\"lifeCycleStages\":\""); + strcat(parameters, fu_smzqzt == NULL ? "" : fu_smzqzt); + strcat(parameters, "\","); + strcat(parameters, "\"version\":\""); + strcat(parameters, fu_item_revision_id == NULL ? "" : fu_item_revision_id); + strcat(parameters, "\","); + strcat(parameters, "\"componentType\":\""); + strcat(parameters, fu_object_name == NULL ? "" : fu_object_name); + strcat(parameters, "\","); + strcat(parameters, "\"bomProductNumber1\":\""); + strcat(parameters, fu_cph == NULL ? "" : fu_cph); + strcat(parameters, "\","); + strcat(parameters, "\"usingOrgName\":\""); + strcat(parameters, organizeNameStr == NULL ? "" : organizeNameStr); + strcat(parameters, "\","); + strcat(parameters, "\"usingOrgCode\":\""); + strcat(parameters, organizeCodeStr == NULL ? "" : organizeCodeStr); + strcat(parameters, "\","); + strcat(parameters, "\"bomDetail\":["); + + DOFREE(organizeNameStr); + DOFREE(organizeCodeStr); + + + for (int i = 0; i < count; i++) + { + tag_t zi_rev = NULLTAG; + AOM_ask_value_tag(children_line[i], "bl_line_object", &zi_rev); + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(zi_rev, &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + WriteLog(">> classId: %s\n", classId); + attrMap = getClassAttrMapRule(classMap, classId); + } + char* itemType = NULL; + AOM_ask_value_string(zi_rev, "object_type", &itemType); + WriteLog("object_type: %s\n", itemType); + char* zi_item_id = NULL; + char* zi_smzqzt = NULL; + char* zi_item_revision_id = NULL; + char* zi_object_name = NULL; + char* zi_cph = NULL; + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_id", &zi_item_id)); + + + if (strcmp("RB3_GNLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_smzqtz", &fu_smzqzt)); + } + else { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_smzqzt", &zi_smzqzt)); + } + + + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_revision_id", &zi_item_revision_id)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &zi_object_name)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_cph", &zi_cph)); + char* zi_uom = NULL; + char* zi_quantity = NULL; + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_uom", &zi_uom)); + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_quantity", &zi_quantity)); + strcat(parameters, "{"); + strcat(parameters, "\"componentCode\":\""); + strcat(parameters, zi_item_id == NULL ? "" : zi_item_id); + strcat(parameters, "\","); + strcat(parameters, "\"theLifecycle\":\""); + strcat(parameters, zi_smzqzt == NULL ? "" : zi_smzqzt); + strcat(parameters, "\","); + strcat(parameters, "\"bomObjectVersion\":\""); + strcat(parameters, zi_item_revision_id == NULL ? "" : zi_item_revision_id); + strcat(parameters, "\","); + strcat(parameters, "\"bomObjectType\":\""); + strcat(parameters, zi_object_name == NULL ? "" : zi_object_name); + strcat(parameters, "\","); + strcat(parameters, "\"bomProductNumber\":\""); + strcat(parameters, zi_cph == NULL ? "" : zi_cph); + strcat(parameters, "\","); + strcat(parameters, "\"bomQuantity\":"); + strcat(parameters, zi_quantity == NULL ? "" : zi_quantity); + strcat(parameters, ","); + char* classCode = NULL; + getItemClassRule(c_sql_values, itemType, ico_tag, zi_rev, attrMap, classId, &classCode,errMsg,itemId1); + + + if (errMsg.size() > 0) { + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + if (zi_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (zi_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (zi_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (zi_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (zi_cph != NULL) + { + DOFREE(fu_cph); + } + if (zi_uom != NULL) + { + DOFREE(zi_uom); + } + if (zi_quantity != NULL) + { + DOFREE(zi_quantity); + } + if (classCode != NULL) + { + DOFREE(classCode); + } + if (itemType != NULL) { + DOFREE(itemType); + } + if (fu_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (fu_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (fu_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (fu_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (fu_cph != NULL) + { + DOFREE(fu_cph); + } + if (fu_scgc != NULL) + { + DOFREE(fu_scgc); + } + if (fu_object_type != NULL) + { + DOFREE(fu_object_type); + } + return; + } + + //Ӽλת߼ + if (strstr(zi_uom, "ϵ") != NULL) { + strcat(parameters, "\"parentItemBase\":1,"); + } + else { + WriteLog("zi_uom111 = %s \n", zi_uom); + WriteLog("classCode111 = %s \n", classCode); + if (classCode != NULL) { + if (strcmp("IN07", classCode) == 0 && strstr("L()", zi_uom) != NULL) + { + zi_uom = "WL()"; + strcat(parameters, "\"parentItemBase\":10000,"); + } + else if ((strcmp("IN01", classCode) == 0 || strcmp("IN56", classCode) == 0 || strcmp("IN59", classCode) == 0) && strstr("GM()", zi_uom) != NULL) + { + zi_uom = "T()"; + strcat(parameters, "\"parentItemBase\":1000000,"); + } + else if (strcmp("IN12", classCode) == 0 && strstr("GM()", zi_uom) != NULL) + { + zi_uom = "KG(ǧ)"; + strcat(parameters, "\"parentItemBase\":1000,"); + } + else { + strcat(parameters, "\"parentItemBase\":1,"); + } + } + else { + strcat(parameters, "\"parentItemBase\":1,"); + } + } + strcat(parameters, "\"bomUnit\":\""); + if (unitMap.find(zi_uom) != unitMap.end()) { + strcat(parameters, unitMap[zi_uom].c_str()); + } + else { + strcat(parameters, zi_uom); + } + strcat(parameters, "\""); + strcat(parameters, "}"); + //WriteLog("parameters%d:%s\n", i,parameters); + if (i < count - 1) { + strcat(parameters, ","); + } + if (zi_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (zi_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (zi_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (zi_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (zi_cph != NULL) + { + DOFREE(fu_cph); + } + if (zi_uom != NULL) + { + DOFREE(zi_uom); + } + if (zi_quantity != NULL) + { + DOFREE(zi_quantity); + } + if (classCode != NULL) + { + DOFREE(classCode); + } + if (itemType != NULL) { + DOFREE(itemType); + } + } + if (fu_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (fu_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (fu_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (fu_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (fu_cph != NULL) + { + DOFREE(fu_cph); + } + if (fu_scgc != NULL) + { + DOFREE(fu_scgc); + } + if (fu_object_type != NULL) + { + DOFREE(fu_object_type); + } + strcat(parameters, "]}"); + parameters_vec->push_back(parameters); + free(parameters); + } + for (int i = 0; i < count; i++) + { + int child_count = 0; + tag_t* zi_children_line = NULLTAG; + BOM_line_ask_all_child_lines(children_line[i], &child_count, &zi_children_line); + if (child_count > 0) { + getBomLinePropertyNewRule(children_line[i], c_sql_values, parameters_vec, classMap, factoryMap, unitMap,errMsg,itemId1); + } + } + if (children_line != NULL) + { + DOFREE(children_line); + } + +} + + + +int RB_SendErpBom_New_Rule(EPM_rule_message_t msg) +{ + + char* log_file = NULL; + printf("־ļ\n"); + //char* TO_SRM = (char*)malloc(sizeof("TO_SRM")); + char tc_log_file_name[200] = ""; + strcpy(tc_log_file_name, "RB_SendErpBom_New_Rule"); + CreateLogFile(tc_log_file_name, &log_file); + + + WriteLog("=========================BOM·ERP rule Start===================\n"); + string errMsg = ""; + + //POM_AM__set_application_bypass(true); + int ifail = EPM_go; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + char* job_name = NULL; + ITKCALL(AOM_ask_value_string(rootTask, "job_name", &job_name)); + WriteLog("ƣ%s\n", job_name); + int email_count = 0; + char** email_values; + ITKCALL(PREF_ask_char_values("RB_SEND_ERP_EMAIL", &email_count, &email_values)); + + vector mail_addrs; + + if (email_count > 0) { + + int valueCount = 0; + char** valueChar = new char* [128]; + //ַָ + split(email_values[0], ";", valueChar, &valueCount); + for (int i = 0; i < valueCount; i++) { + mail_addrs.push_back(valueChar[i]); + } + } + + + int user_cnt = mail_addrs.size(); + WriteLog("user_cnt===%d\n", user_cnt); + + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + WriteLog("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + CloseLog(); + return 1; + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + + char errorMessage[100000] = "";//д뵽ļֵ + for (int i = 0; i < attachments_num; i++) + { + char* itemType = NULL; + AOM_ask_value_string(attachments[i], "object_type", &itemType); + WriteLog("itemType%s\n", itemType); + + //˵ǰ汾Ķ + //20250721 Ӵ + if (strcmp(itemType, "RB3_BZJBJRevision") == 0 || strcmp(itemType, "RB3_BZJRevision") == 0 || strcmp(itemType, "RB3_GNLBJRevision") == 0 || strcmp(itemType, "RB3_GNZCRevision") == 0 || strcmp(itemType, "RB3_GQBJRevision") == 0 || strcmp(itemType, "RB3_GQRevision") == 0 || strcmp(itemType, "RB3_GZBJRevision") == 0 || strcmp(itemType, "RB3_GZRevision") == 0 || strcmp(itemType, "RB3_LBJRevision") == 0 || strcmp(itemType, "RB3_SLRevision") == 0 || strcmp(itemType, "RB3_TJJRevision") == 0 || strcmp(itemType, "RB3_TXTRevision") == 0 || strcmp(itemType, "RB3_WJTLRevision") == 0 || strcmp(itemType, "RB3_XJRevision") == 0 || strcmp(itemType, "RB3_XZCPRevision") == 0 || strcmp(itemType, "RB3_XZLBJRevision") == 0 || strcmp(itemType, "RB3_YCLRevision") == 0 || strcmp(itemType, "RB3_YZRevision") == 0 || strcmp(itemType, "RB3_ZCRevision") == 0) + { + char* itemId1 = NULL; + AOM_ask_value_string(attachments[i], "item_id", &itemId1); + WriteLog("itemId1%s\n", itemId1); + //ȡ + tag_t top_line = NULLTAG, window = NULLTAG; + BOM_create_window(&window); + //öBOM + BOM_set_window_top_line(window, NULLTAG, attachments[i], NULLTAG, &top_line); + //ȡjsonַ + vector parameters_vec; + map> classMap; + map> factoryMap; + WriteLog("=========================ȡӼϢ===================\n"); + getBomLinePropertyNewRule(top_line, c_sql_values, ¶meters_vec, classMap, factoryMap, unitMap, errMsg,itemId1); + if (errMsg.size() > 0) { + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + DOFREE(itemType); + MEM_free(attachments); + MEM_free(c_sql_values); + + + //ʼ + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-BOM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + + return EPM_go; + } + + + DOFREE(itemType); + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "{\"data\":["); + for (int i = 0; i < parameters_vec.size(); i++) + { + strcat(parameters, parameters_vec[i].c_str()); + if (i < parameters_vec.size() - 1) { + strcat(parameters, ","); + } + } + strcat(parameters, "],\"control\":{\"keydata\":null,\"ifid\": null,\"ifno\":\"JDE_MDM_BOM_01\",\"suser\": null,\"sysid\": null}}"); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + WriteLog("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + ////strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@BOM"); + //strcat(cmd,handler_name); + //WriteLog("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + WriteLog("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + strResult = strResult.substr(0, iSize - 1); + cout << strResult << endl; + if (strstr(strResult.c_str(), "\"code\":200") != NULL) + { + WriteLog("·ɹ\n"); + + + } + else { + ifail = EPM_go; + strcat(errorMessage, strResult.c_str()); + + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-BOM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":ʧ->"); + strcat_s(cmd, errorMessage); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + + + } + } + DOFREE(itemType); + } + } + + MEM_free(attachments); + MEM_free(c_sql_values); + /*if (ifail == EPM_nogo) + { + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + + }*/ + WriteLog("=========================BOM·ERP rule End===================\n"); + CloseLog(); + return ifail; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_SendErpBom_Rule_Release.cxx b/CONNOR_ITK/RB_SendErpBom_Rule_Release.cxx new file mode 100644 index 0000000..8703a18 --- /dev/null +++ b/CONNOR_ITK/RB_SendErpBom_Rule_Release.cxx @@ -0,0 +1,1323 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" +#include "OracleDB.h" + + + +map getClassAttrMapRuleRelease(map> classMap, char* classId) { + map attrMap; + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + return attrMap; +} +void getItemClassRuleRelease(char** c_sql_values, char* itemType, tag_t ico_tag, tag_t zi_rev, map attrMap, char* classId, char** classCode, string& errMsg, char* itemId1) { + WriteLog("-----------------getItemClass------------------------\n"); + + char* field1 = NULL; + char* field2 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0) { + if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field1); + DOFREE(value); + } + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field2)); + } + else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* new_classId = NULL; + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) + { + new_classId = getFirstStr(classId, 2); + } + else + { + new_classId = getFirstStr(classId, 4); + } + tag_t classTag = NULLTAG; + char* id = NULL; + if (new_classId != NULL) { + ITKCALL(ICS_find_class(new_classId, &classTag)); + if (classTag != NULLTAG) + { + ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); + } + } + if (id != NULL) { + DOFREE(id); + } + if (classTag != NULL) { + DOFREE(classTag); + } + if (new_classId != NULL) { + DOFREE(new_classId); + } + } + if (field1 != NULL) { + if (field1 != NULL && field2 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s' and PFIELD02= '%s'", field1, field2); + } + else { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + } + } + else { + if (strcmp("RB3_ZCRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_zclx", &field1)); + } + else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 + || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 + || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 + || strcmp("RB3_GZBJRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &field1)); + WriteLog("ʾ:field1T==%s\n", field1); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0 + || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_bjlx", &field1)); + } + else if (strcmp("RB3_XZCPRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_cplx2", &field1)); + } + else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field1); + DOFREE(value); + } + } + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + + //sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + } + if (strcmp("", sql) != 0) { + WriteLog("ʾ:sqlT==%s\n", sql); + // ʼ OCILIB + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + if (db.executeQuery(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + if (field1 != NULL) { + char sql2[128] = "\0"; + sprintf(sql2, "select PCLASSCODE,PCLASSNAME from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + WriteLog("ʾ:sql2T==%s\n", sql2); + if (db.executeQuery(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql2); + } + } + + } + + } + db.disconnect(); + + WriteLog("outputValueCount=%d\n", outputValueCount); + WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + if (outputValueCount > 0) { + *classCode = outputValue[0][0]; + WriteLog("Ϸ====%s\n", *classCode); + } + else { + + errMsg.append(itemId1); + errMsg.append("Ϸѯʧ,PLM_ERP_FACTORY_TABLE"); + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + return; + + } + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + + +} + + +void getBomLinePropertyNewRuleRelease(tag_t topLine, char** c_sql_values, vector* parameters_vec, map> classMap, map> factoryMap, map unitMap, string& errMsg, char* itemId1) +{ + WriteLog("ʼȡӼϢ\n"); + tag_t fu_rev = NULLTAG; + AOM_ask_value_tag(topLine, "bl_line_object", &fu_rev); + + tag_t* children_line = NULLTAG; + int count = 0; + + BOM_line_ask_all_child_lines(topLine, &count, &children_line); + if (count > 0) { + + char* fu_item_id = NULL; + char* fu_smzqzt = NULL; + char* fu_item_revision_id = NULL; + char* fu_object_name = NULL; + char* fu_object_type = NULL; + char* fu_cph = NULL; + char** fu_scgc = NULL; + int factoryCount = 0; + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_id", &fu_item_id)); + + ITKCALL(AOM_UIF_ask_value(fu_rev, "item_revision_id", &fu_item_revision_id)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "object_name", &fu_object_name)); + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cph", &fu_cph)); + char* itemType = NULL; + AOM_ask_value_string(fu_rev, "object_type", &itemType); + + if (strcmp("RB3_GNLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_smzqtz", &fu_smzqzt)); + } + else { + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_smzqzt", &fu_smzqzt)); + } + + + + if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_xzscgc", &factoryCount, &fu_scgc)); + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 + || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_scgc", &factoryCount, &fu_scgc)); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_sygc1", &factoryCount, &fu_scgc)); + } + else { + ITKCALL(AOM_UIF_ask_values(fu_rev, "rb3_scgc1", &factoryCount, &fu_scgc)); + } + ITKCALL(AOM_ask_value_string(fu_rev, "object_type", &fu_object_type)); + + WriteLog("111\n"); + char facttoryNameStr[10000] = "\0"; + char factoryCodeStr[10000] = "\0"; + char organizeNameStr[15000] = "\0"; + char organizeCodeStr[15000] = "\0"; + WriteLog("222\n"); + //д,ʵ(ͬ) + //֯⴦,ͨݿƥ + + for (int i = 0; i < factoryCount; i++) + { + if (factoryMap.find(fu_scgc[i]) == factoryMap.end()) { + char* factoryCode = NULL; + char* factoryName = NULL; + int factoryColumn = 0, factoryValueCount = 0; + char*** factoryValue = NULL; + char factorySql[128] = "\0"; + + + if (fu_scgc[i] == NULL || strcmp(fu_scgc[i], "") == 0 || strcmp(fu_scgc[i], "0") == 0) { + sprintf(factorySql, "select PFACTORYCODE,PFACTORYNAME from PLM_ERP_FACTORY_TABLE where PFACTORY= 'globa100'"); + + } + else { + sprintf(factorySql, "select PFACTORYCODE,PFACTORYNAME from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", fu_scgc[i]); + + } + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + if (db.executeQuery(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + + } + + + + db.disconnect(); + WriteLog("ʾ:factorySql==%s\n", factorySql); + + WriteLog("factoryValueCount=%d\n", factoryValueCount); + WriteLog("factoryColumn=%d\n", factoryColumn); + if (factoryValueCount > 0) { + factoryCode = factoryValue[0][0]; + factoryName = factoryValue[0][1]; + vector factoryVec; + factoryVec.push_back(factoryCode); + factoryVec.push_back(factoryName); + factoryMap[fu_scgc[i]] = factoryVec; + //WriteLog("֯====%s\n", factoryCode); + //WriteLog("֯====%s\n", factoryName); + if (strcmp(facttoryNameStr, "") != 0) { + strcat(facttoryNameStr, ","); + strcat(factoryCodeStr, ","); + } + if (factoryName != NULL) { + strcat(facttoryNameStr, factoryName); + } + if (factoryCode != NULL) { + strcat(factoryCodeStr, factoryCode); + } + + } + else { + + + errMsg.append(itemId1); + errMsg.append("֯ѯʧ,PLM_ERP_FACTORY_TABLE"); + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + + if (factoryValue != NULL) { + for (int o = 0; o < factoryValueCount; ++o) + { + for (int k = 0; k < factoryValueCount; ++k) { + delete[] factoryValue[o][k]; // ͷÿַ + } + delete[] factoryValue[o]; // ͷڲָ + + } + // ͷмָ + delete[] factoryValue; // ͷָ + + // ָÿգָ + factoryValue = nullptr; + } + + + if (factoryCode != NULL) { + DOFREE(factoryCode); + } + if (factoryName != NULL) { + DOFREE(factoryName); + } + return; + + } + + if (factoryValue != NULL) { + for (int o = 0; o < factoryValueCount; ++o) + { + for (int k = 0; k < factoryValueCount; ++k) { + delete[] factoryValue[o][k]; // ͷÿַ + } + delete[] factoryValue[o]; // ͷڲָ + + } + // ͷмָ + delete[] factoryValue; // ͷָ + + // ָÿգָ + factoryValue = nullptr; + } + if (factoryCode != NULL) { + DOFREE(factoryCode); + } + if (factoryName != NULL) { + DOFREE(factoryName); + } + } + else { + vector factoryVec = factoryMap[fu_scgc[i]]; + if (strcmp(facttoryNameStr, "") != 0) { + strcat(facttoryNameStr, ","); + strcat(factoryCodeStr, ","); + } + strcat(factoryCodeStr, factoryVec[0].c_str()); + strcat(facttoryNameStr, factoryVec[1].c_str()); + + } + + } + char* fu_class_code = NULL; + tag_t fu_ico_tag = NULLTAG; + char* fu_class_id = NULL; + map fuAttrMap; + ICS_ask_classification_object(fu_rev, &fu_ico_tag); + if (fu_ico_tag != NULLTAG) { + ICS_ico_ask_class(fu_ico_tag, &fu_class_id); + WriteLog(">> fu_class_id: %s\n", fu_class_id); + fuAttrMap = getClassAttrMapRuleRelease(classMap, fu_class_id); + } + getItemClassRuleRelease(c_sql_values, fu_object_type, fu_ico_tag, fu_rev, fuAttrMap, fu_class_id, &fu_class_code, errMsg, itemId1); + + if (errMsg.size() > 0) { + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + + + if (fu_class_code != NULL) { + DOFREE(fu_class_code); + } + if (fu_class_id != NULL) { + DOFREE(fu_class_id); + } + return; + } + + + //֯߼ + char* organizeCode = NULL; + char* organizeName = NULL; + char* organizeFactory = NULL; + char factorySql2[128] = "\0"; + int organizeColumn = 0, organizeValueCount = 0; + char*** organizeValue = NULL; + WriteLog("fu_object_type: %s\n", fu_object_type); + WriteLog("fu_class_code: %s\n", fu_class_code); + WriteLog("fu_item_id: %s\n", fu_item_id); + if (strcmp("RB3_LBJRevision", fu_object_type) == 0) { + sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where CLASSCODE= '%s'", fu_class_code); + WriteLog("ʾ:factorySql2==%s\n", factorySql2); + + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + + + if (db.executeQuery(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factorySql2); + } + } + + + + db.disconnect(); + + //WriteLog("factoryValueCount=%d\n", organizeValueCount); + //WriteLog("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeFactory = organizeValue[0][0]; + organizeCode = organizeValue[0][1]; + organizeName = organizeValue[0][2]; + WriteLog("֯====%s\n", organizeFactory); + WriteLog("֯2====%s\n", organizeName); + WriteLog("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeFactory != NULL && strcmp("", organizeFactory) != 0 && strcmp("NULL", organizeFactory) != 0) { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0 && strcmp("", organizeName) != 0) { + if (strcmp(organizeNameStr, "") != 0) { + strcat(organizeNameStr, ","); + } + strcat(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0 && strcmp("", organizeCode) != 0) { + if (strcmp(organizeCodeStr, "") != 0) { + strcat(organizeCodeStr, ","); + } + strcat(organizeCodeStr, organizeCode); + } + } + else if (strcmp("RB3_XZCPRevision", fu_object_type) == 0) { + char* field1 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + ITKCALL(AOM_UIF_ask_value(fu_rev, "rb3_cplx2", &field1)); + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + + if (db.executeQuery(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + else { + //WriteLog("outputValueCount=%d\n", outputValueCount); + //WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + char* fuClassCode = NULL; + if (outputValueCount > 0) { + fuClassCode = outputValue[0][0]; + //WriteLog("Ϸ====%s\n", fuClassCode); + } + if (strcmp("IN07", fuClassCode) == 0) { + sprintf(factorySql2, "select PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where PTYPE= 'RB3_GNZCRevision' and PFIELD01= ''"); + WriteLog("ʾ:factorySql2==%s\n", factorySql2); + if (db.executeQuery(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + } + //WriteLog("factoryValueCount=%d\n", organizeValueCount); + //WriteLog("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeCode = organizeValue[0][0]; + organizeName = organizeValue[0][1]; + WriteLog("֯2====%s\n", organizeName); + WriteLog("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0) { + strcpy(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0) { + strcpy(organizeCodeStr, organizeCode); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (fuClassCode != NULL) { + DOFREE(fuClassCode); + } + } + } + + + + db.disconnect(); + + + + if (field1 != NULL) { + DOFREE(field1); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + } + else if (strcmp("RB3_BZJRevision", fu_object_type) == 0) { + char* field1 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + //Ϸ⴦,ͨݿƥ + char sql[1024] = "\0"; + ITKCALL(AOM_UIF_ask_value(fu_rev, "object_name", &field1)); + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); + } + if (!OCI_Initialize(nullptr, nullptr, OCI_ENV_DEFAULT)) { + std::cerr << "OCILIB ʼʧ" << std::endl; + } + OracleDB db; + boolean status = db.connect(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + if (!status) { // 滻ΪʵʵϢ + std::cerr << "ݿʧ" << std::endl; + OCI_Cleanup(); + } + else { + if (db.executeQuery(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + else { + //WriteLog("outputValueCount=%d\n", outputValueCount); + //WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + char* fuClassCode = NULL; + if (outputValueCount > 0) { + fuClassCode = outputValue[0][0]; + //WriteLog("Ϸ====%s\n", fuClassCode); + } + if (strcmp("IN07", fuClassCode) == 0) { + sprintf(factorySql2, "select PFACTORY,PFACTORYCODE,PFACTORYNAME from PLM_FACTORY_ORGANIZE_TABLE where CLASSCODE= '%s'", fuClassCode); + WriteLog("ʾ:factorySql2==%s\n", factorySql2); + + + if (db.executeQuery(factorySql2, &organizeColumn, &organizeValueCount, &organizeValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factoryCodeStr); + } + + + //WriteLog("factoryValueCount=%d\n", organizeValueCount); + //WriteLog("factoryColumn=%d\n", organizeColumn); + if (organizeValueCount > 0) { + organizeFactory = organizeValue[0][0]; + organizeCode = organizeValue[0][1]; + organizeName = organizeValue[0][2]; + WriteLog("֯====%s\n", organizeFactory); + WriteLog("֯2====%s\n", organizeName); + WriteLog("֯2====%s\n", organizeCode); + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + if (organizeFactory != NULL && strcmp("", organizeFactory) != 0 && strcmp("NULL", organizeFactory) != 0) { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (organizeName != NULL && strcmp("NULL", organizeName) != 0 && strcmp("", organizeName) != 0) { + if (strcmp(organizeNameStr, "") != 0) { + strcat(organizeNameStr, ","); + } + strcat(organizeNameStr, organizeName); + } + if (organizeCode != NULL && strcmp("NULL", organizeCode) != 0 && strcmp("", organizeCode) != 0) { + if (strcmp(organizeCodeStr, "") != 0) { + strcat(organizeCodeStr, ","); + } + strcat(organizeCodeStr, organizeCode); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + } + if (fuClassCode != NULL) { + DOFREE(fuClassCode); + } + } + + } + + + + db.disconnect(); + if (field1 != NULL) { + DOFREE(field1); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + } + else { + strcpy(organizeNameStr, facttoryNameStr); + strcpy(organizeCodeStr, factoryCodeStr); + + } + + if (organizeCode != NULL) { + DOFREE(organizeCode); + } + if (organizeName != NULL) { + DOFREE(organizeName); + } + if (organizeFactory != NULL) { + DOFREE(organizeFactory); + } + if (organizeValue != NULL) { + for (int o = 0; o < organizeValueCount; ++o) + { + for (int k = 0; k < organizeValueCount; ++k) { + delete[] organizeValue[o][k]; // ͷÿַ + } + delete[] organizeValue[o]; // ͷڲָ + + } + // ͷмָ + delete[] organizeValue; // ͷָ + + // ָÿգָ + organizeValue = nullptr; + } + if (fu_class_code != NULL) { + DOFREE(fu_class_code); + } + if (fu_class_id != NULL) { + DOFREE(fu_class_id); + } + DOFREE(facttoryNameStr); + DOFREE(factoryCodeStr); + + WriteLog("count:%d\n", count); + // ʼԤ󳤶 + size_t buffer_size = 150000; // ʼСɸʵ + char* parameters = static_cast(malloc(buffer_size)); + + parameters[0] = '\0'; // ȷַԿַʼ + strcat(parameters, "{"); + + //AOM_ask_value_string(children_line[i], "fnd0bl_line_object_type", &itemType); + strcat(parameters, "\"parentPartCode\":\""); + strcat(parameters, fu_item_id == NULL ? "" : fu_item_id); + strcat(parameters, "\","); + strcat(parameters, "\"lifeCycleStages\":\""); + strcat(parameters, fu_smzqzt == NULL ? "" : fu_smzqzt); + strcat(parameters, "\","); + strcat(parameters, "\"version\":\""); + strcat(parameters, fu_item_revision_id == NULL ? "" : fu_item_revision_id); + strcat(parameters, "\","); + strcat(parameters, "\"componentType\":\""); + strcat(parameters, fu_object_name == NULL ? "" : fu_object_name); + strcat(parameters, "\","); + strcat(parameters, "\"bomProductNumber1\":\""); + strcat(parameters, fu_cph == NULL ? "" : fu_cph); + strcat(parameters, "\","); + strcat(parameters, "\"usingOrgName\":\""); + strcat(parameters, organizeNameStr == NULL ? "" : organizeNameStr); + strcat(parameters, "\","); + strcat(parameters, "\"usingOrgCode\":\""); + strcat(parameters, organizeCodeStr == NULL ? "" : organizeCodeStr); + strcat(parameters, "\","); + strcat(parameters, "\"bomDetail\":["); + + + DOFREE(organizeNameStr); + DOFREE(organizeCodeStr); + + for (int i = 0; i < count; i++) + { + tag_t zi_rev = NULLTAG; + AOM_ask_value_tag(children_line[i], "bl_line_object", &zi_rev); + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(zi_rev, &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + WriteLog(">> classId: %s\n", classId); + attrMap = getClassAttrMapRuleRelease(classMap, classId); + } + char* itemType = NULL; + AOM_ask_value_string(zi_rev, "object_type", &itemType); + WriteLog("object_type: %s\n", itemType); + char* zi_item_id = NULL; + char* zi_smzqzt = NULL; + char* zi_item_revision_id = NULL; + char* zi_object_name = NULL; + char* zi_cph = NULL; + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_id", &zi_item_id)); + + + if (strcmp("RB3_GNLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_smzqtz", &fu_smzqzt)); + } + else { + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_smzqzt", &zi_smzqzt)); + } + + + + + + ITKCALL(AOM_UIF_ask_value(zi_rev, "item_revision_id", &zi_item_revision_id)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "object_name", &zi_object_name)); + ITKCALL(AOM_UIF_ask_value(zi_rev, "rb3_cph", &zi_cph)); + char* zi_uom = NULL; + char* zi_quantity = NULL; + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_uom", &zi_uom)); + ITKCALL(AOM_UIF_ask_value(children_line[i], "bl_quantity", &zi_quantity)); + strcat(parameters, "{"); + strcat(parameters, "\"componentCode\":\""); + strcat(parameters, zi_item_id == NULL ? "" : zi_item_id); + strcat(parameters, "\","); + strcat(parameters, "\"theLifecycle\":\""); + strcat(parameters, zi_smzqzt == NULL ? "" : zi_smzqzt); + strcat(parameters, "\","); + strcat(parameters, "\"bomObjectVersion\":\""); + strcat(parameters, zi_item_revision_id == NULL ? "" : zi_item_revision_id); + strcat(parameters, "\","); + strcat(parameters, "\"bomObjectType\":\""); + strcat(parameters, zi_object_name == NULL ? "" : zi_object_name); + strcat(parameters, "\","); + strcat(parameters, "\"bomProductNumber\":\""); + strcat(parameters, zi_cph == NULL ? "" : zi_cph); + strcat(parameters, "\","); + strcat(parameters, "\"bomQuantity\":"); + strcat(parameters, zi_quantity == NULL ? "" : zi_quantity); + strcat(parameters, ","); + char* classCode = NULL; + getItemClassRuleRelease(c_sql_values, itemType, ico_tag, zi_rev, attrMap, classId, &classCode, errMsg, itemId1); + + + if (errMsg.size() > 0) { + //EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + if (zi_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (zi_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (zi_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (zi_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (zi_cph != NULL) + { + DOFREE(fu_cph); + } + if (zi_uom != NULL) + { + DOFREE(zi_uom); + } + if (zi_quantity != NULL) + { + DOFREE(zi_quantity); + } + if (classCode != NULL) + { + DOFREE(classCode); + } + if (itemType != NULL) { + DOFREE(itemType); + } + if (fu_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (fu_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (fu_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (fu_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (fu_cph != NULL) + { + DOFREE(fu_cph); + } + if (fu_scgc != NULL) + { + DOFREE(fu_scgc); + } + if (fu_object_type != NULL) + { + DOFREE(fu_object_type); + } + return; + } + + //Ӽλת߼ + if (strstr(zi_uom, "ϵ") != NULL) { + strcat(parameters, "\"parentItemBase\":1,"); + } + else { + WriteLog("zi_uom111 = %s \n", zi_uom); + WriteLog("classCode111 = %s \n", classCode); + if (classCode != NULL) { + if (strcmp("IN07", classCode) == 0 && strstr("L()", zi_uom) != NULL) + { + zi_uom = "WL()"; + strcat(parameters, "\"parentItemBase\":10000,"); + } + else if ((strcmp("IN01", classCode) == 0 || strcmp("IN56", classCode) == 0 || strcmp("IN59", classCode) == 0) && strstr("GM()", zi_uom) != NULL) + { + zi_uom = "T()"; + strcat(parameters, "\"parentItemBase\":1000000,"); + } + else if (strcmp("IN12", classCode) == 0 && strstr("GM()", zi_uom) != NULL) + { + zi_uom = "KG(ǧ)"; + strcat(parameters, "\"parentItemBase\":1000,"); + } + else { + strcat(parameters, "\"parentItemBase\":1,"); + } + } + else { + strcat(parameters, "\"parentItemBase\":1,"); + } + } + strcat(parameters, "\"bomUnit\":\""); + if (unitMap.find(zi_uom) != unitMap.end()) { + strcat(parameters, unitMap[zi_uom].c_str()); + } + else { + strcat(parameters, zi_uom); + } + strcat(parameters, "\""); + strcat(parameters, "}"); + //WriteLog("parameters%d:%s\n", i,parameters); + if (i < count - 1) { + strcat(parameters, ","); + } + if (zi_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (zi_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (zi_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (zi_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (zi_cph != NULL) + { + DOFREE(fu_cph); + } + if (zi_uom != NULL) + { + DOFREE(zi_uom); + } + if (zi_quantity != NULL) + { + DOFREE(zi_quantity); + } + if (classCode != NULL) + { + DOFREE(classCode); + } + if (itemType != NULL) { + DOFREE(itemType); + } + } + if (fu_item_id != NULL) + { + DOFREE(fu_item_id); + } + if (fu_smzqzt != NULL) + { + DOFREE(fu_smzqzt); + } + if (fu_item_revision_id != NULL) + { + DOFREE(fu_item_revision_id); + } + if (fu_object_name != NULL) + { + DOFREE(fu_object_name); + } + if (fu_cph != NULL) + { + DOFREE(fu_cph); + } + if (fu_scgc != NULL) + { + DOFREE(fu_scgc); + } + if (fu_object_type != NULL) + { + DOFREE(fu_object_type); + } + + strcat(parameters, "]}"); + parameters_vec->push_back(parameters); + free(parameters); + } + for (int i = 0; i < count; i++) + { + int child_count = 0; + tag_t* zi_children_line = NULLTAG; + BOM_line_ask_all_child_lines(children_line[i], &child_count, &zi_children_line); + if (child_count > 0) { + getBomLinePropertyNewRuleRelease(children_line[i], c_sql_values, parameters_vec, classMap, factoryMap, unitMap, errMsg, itemId1); + } + } + if (children_line != NULL) + { + DOFREE(children_line); + } + +} + + + +int RB_SendErpBom_New_Rule_Release(EPM_rule_message_t msg) +{ + + + char* log_file = NULL; + WriteLog("־ļ\n"); + //char* TO_SRM = (char*)malloc(sizeof("TO_SRM")); + char tc_log_file_name[200] = ""; + strcpy(tc_log_file_name, "RB_SendErpBom_New_Rule_Release"); + CreateLogFile(tc_log_file_name, &log_file); + + WriteLog("=========================BOM·ERP rule Start===================\n"); + string errMsg = ""; + + //POM_AM__set_application_bypass(true); + int ifail = EPM_go; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + + char* job_name = NULL; + ITKCALL(AOM_ask_value_string(rootTask, "job_name", &job_name)); + WriteLog("ƣ%s\n", job_name); + int email_count = 0; + char** email_values; + ITKCALL(PREF_ask_char_values("RB_SEND_ERP_EMAIL", &email_count, &email_values)); + + vector mail_addrs; + + if (email_count > 0) { + + int valueCount = 0; + char** valueChar = new char* [128]; + //ַָ + split(email_values[0], ";", valueChar, &valueCount); + for (int i = 0; i < valueCount; i++) { + mail_addrs.push_back(valueChar[i]); + } + } + + int user_cnt = mail_addrs.size(); + WriteLog("user_cnt===%d\n", user_cnt); + + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + WriteLog("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + CloseLog(); + return EPM_nogo; + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + + char errorMessage[100000] = "";//д뵽ļֵ + for (int i = 0; i < attachments_num; i++) + { + char* itemType = NULL; + AOM_ask_value_string(attachments[i], "object_type", &itemType); + WriteLog("itemType%s\n", itemType); + + //˵ǰ汾Ķ + //20250721 Ӵ + if (strcmp(itemType, "RB3_BZJBJRevision") == 0 || strcmp(itemType, "RB3_BZJRevision") == 0 || strcmp(itemType, "RB3_GNLBJRevision") == 0 || strcmp(itemType, "RB3_GNZCRevision") == 0 || strcmp(itemType, "RB3_GQBJRevision") == 0 || strcmp(itemType, "RB3_GQRevision") == 0 || strcmp(itemType, "RB3_GZBJRevision") == 0 || strcmp(itemType, "RB3_GZRevision") == 0 || strcmp(itemType, "RB3_LBJRevision") == 0 || strcmp(itemType, "RB3_SLRevision") == 0 || strcmp(itemType, "RB3_TJJRevision") == 0 || strcmp(itemType, "RB3_TXTRevision") == 0 || strcmp(itemType, "RB3_WJTLRevision") == 0 || strcmp(itemType, "RB3_XJRevision") == 0 || strcmp(itemType, "RB3_XZCPRevision") == 0 || strcmp(itemType, "RB3_XZLBJRevision") == 0 || strcmp(itemType, "RB3_YCLRevision") == 0 || strcmp(itemType, "RB3_YZRevision") == 0 || strcmp(itemType, "RB3_ZCRevision") == 0) + { + char* itemId1 = NULL; + AOM_ask_value_string(attachments[i], "item_id", &itemId1); + WriteLog("itemId1%s\n", itemId1); + //ȡ + tag_t top_line = NULLTAG, window = NULLTAG; + BOM_create_window(&window); + //öBOM + BOM_set_window_top_line(window, NULLTAG, attachments[i], NULLTAG, &top_line); + //ȡjsonַ + vector parameters_vec; + map> classMap; + map> factoryMap; + WriteLog("=========================ȡӼϢ===================\n"); + getBomLinePropertyNewRuleRelease(top_line, c_sql_values, ¶meters_vec, classMap, factoryMap, unitMap, errMsg, itemId1); + if (errMsg.size() > 0) { + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + + DOFREE(itemType); + MEM_free(attachments); + MEM_free(c_sql_values); + + //ʼ + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-BOM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + CloseLog(); + return EPM_nogo; + } + + + DOFREE(itemType); + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "{\"data\":["); + for (int i = 0; i < parameters_vec.size(); i++) + { + strcat(parameters, parameters_vec[i].c_str()); + if (i < parameters_vec.size() - 1) { + strcat(parameters, ","); + } + } + strcat(parameters, "],\"control\":{\"keydata\":null,\"ifid\": null,\"ifno\":\"JDE_MDM_BOM_01\",\"suser\": null,\"sysid\": null}}"); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + WriteLog("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + ////strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@BOM"); + //strcat(cmd,handler_name); + //WriteLog("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + WriteLog("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + strResult = strResult.substr(0, iSize - 1); + cout << strResult << endl; + if (strstr(strResult.c_str(), "\"code\":200") != NULL) + { + WriteLog("·ɹ\n"); + + + } + else { + ifail = EPM_nogo; + strcat(errorMessage, strResult.c_str()); + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-BOM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":ʧ->"); + strcat_s(cmd, errorMessage); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + } + } + DOFREE(itemType); + } + } + + MEM_free(attachments); + MEM_free(c_sql_values); + if (ifail == EPM_nogo) + { + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + + } + WriteLog("=========================BOM·ERP rule Release End===================\n"); + CloseLog(); + return ifail; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_SendErpItem.cxx b/CONNOR_ITK/RB_SendErpItem.cxx new file mode 100644 index 0000000..5b5e498 --- /dev/null +++ b/CONNOR_ITK/RB_SendErpItem.cxx @@ -0,0 +1,2945 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" + +int RB_SendErpItem(EPM_action_message_t msg) +{ + printf("=========================·ERP Start===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, *attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + //ȡ + char *argflag = NULL, *argvalue = NULL, *arg = NULL; + char messageUser[1024] = "", messageResult[1024] = ""; + int arg_cnt = TC_number_of_arguments(msg.arguments); + printf("Ϊ%d\n", arg_cnt); + if (arg_cnt > 0) + { + for (int i = 0; i messageUserValues; + + if (strstr(messageUser, ",") != NULL) + { + int vectorValueCount = 0; + char ** vectorValueChar = new char *[64]; + split(messageUser, ",", vectorValueChar, &vectorValueCount); + for (int i = 0; i < vectorValueCount; i++) + { + messageUserValues.push_back(vectorValueChar[i]); + } + } + else + { + messageUserValues.push_back(messageUser); + } + + int pref_cnt = 0; + char ** pref_vals = NULL; + char* deleteTZRevision = new char[2048];//˵ͼֽ汾 + //ȡѡֵ + PREF_ask_char_values("RB_ItemSendErpProperty", &pref_cnt, &pref_vals); + map typePropertyType; + for (int j = 0; j < pref_cnt; j++) + { + if (strstr(pref_vals[j], "-") != NULL) + { + //-в֡ + int valueCount = 0; + char ** valueChar = new char *[64]; + //ַָ + split(pref_vals[j], "-", valueChar, &valueCount); + typePropertyType[valueChar[0]] = valueChar[1];// .insert(std::pair(valueChar[0], valueChar[1])); + } + //+++ȡҪ˵а汾 + else if(strstr(pref_vals[j], "delete=") != NULL){ + strcpy(deleteTZRevision,pref_vals[j]); + } + //+++ + } + + char *tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + + for (int i = 0; i < attachments_num; i++) + { + char *itemType = NULL; + AOM_ask_value_string(attachments[i], "object_type", &itemType); + + printf("itemType%s\n", itemType); + //˵ǰ汾Ķ + if ((strstr(itemType, "Revision") == NULL) || (strstr(itemType, "Master") != NULL) + || (strstr(itemType, "master") != NULL) || (strstr(itemType, "BOM") != NULL) || (strstr(itemType, "bom") != NULL) || (strstr(itemType, "Bom") != NULL)) + { + DOFREE(itemType); + continue; + } + //+++˰汾 + if (strstr(deleteTZRevision, itemType) != NULL) { + DOFREE(itemType); + continue; + } + //+++ + bool isStart = true; + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "getItemPropertys}}"); + strcat(parameters, "["); + //ȡǰʱ + time_t now = time(0); + tm *p = localtime(&now); + + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + string propertyNames = typePropertyType[itemType]; + + if (propertyNames.c_str() != NULL && propertyNames.size() > 0) + { + printf("propertyNames%s\n", propertyNames.c_str()); + + int factoryNum = 0; + char ** factoryValues = NULL; + char * localization_status; + logical master; + //ȡ + const char * constName = propertyNames.c_str(); + char* name = new char[2048];//㹻 + strcpy(name, constName); + if (strstr(name, ",") != NULL) + { + //,в֡ + int valueCount = 0; + char ** valueChar = new char *[64]; + //ַָ + split(name, ",", valueChar, &valueCount); + for (int k = 0; k < valueCount; k++) + { + if (strstr(valueChar[k], "=") != NULL) + { + //-в֡ + int valueNum = 0; + char ** values = new char *[64]; + //ַָ + split(valueChar[k], "=", values, &valueNum); + + if (strcmp(values[1], "FACTORYNAME") == 0) + { + printf("FACTORYNAME%s\n", values[0]); + if (strcmp(values[0], "/") != 0) + { + AOM_UIF_ask_localized_value_strings(attachments[i], values[0], "zh_CN", &factoryNum, &factoryValues, &localization_status, &master); + } + else + { + factoryNum = 1; + factoryValues = new char*[64]; + factoryValues[0] = ""; + } + //TCGetPropertyValue(attachments[i], "Revision", values[0], &factoryValues); + //AOM_UIF_ask_values(attachments[i], values[0], &factoryNum, &factoryValues); + } + } + } + } + else + { + //-в֡ + int valueCount = 0; + char ** valueChar = new char *[64]; + //ַָ + split(name, "=", valueChar, &valueCount); + if (strcmp(valueChar[1], "FACTORYNAME") == 0) + { + printf("FACTORYNAME%s\n", valueChar[0]); + if (strcmp(valueChar[0], "/") != 0) + { + AOM_UIF_ask_localized_value_strings(attachments[i], valueChar[0], "zh_CN", &factoryNum, &factoryValues, &localization_status, &master); + } + else + { + factoryNum = 1; + factoryValues = new char*[64]; + factoryValues[0] = ""; + } + } + } + + + printf("factoryNum%d\n", factoryNum); + + if (factoryNum > 0) + { + for (int j = 0; j < factoryNum; j++) + { + + printf("factoryValues[j]%s\n", factoryValues[j]); + if (factoryValues[j] == NULL || strcmp(factoryValues[j], "") == 0) + { + continue; + } + if (isStart) + { + strcat(parameters, "{"); + isStart = false; + } + else + { + strcat(parameters, ",{"); + } + + //const char * constName = propertyNames.c_str(); + //char* name = new char[2048];//㹻 + //strcpy(name, constName); + if (strstr(name, ",") != NULL) + { + //,в֡ + int valueCount = 0; + char ** valueChar = new char *[64]; + //ַָ + split(name, ",", valueChar, &valueCount); + for (int k = 0; k < valueCount; k++) + { + if (strstr(valueChar[k], "=") != NULL) + { + //-в֡ + int valueNum = 0; + char ** values = new char *[64]; + //ַָ + split(valueChar[k], "=", values, &valueNum); + + strcat(parameters, "\""); + strcat(parameters, values[1] == NULL || strlen(values[1]) == 0 ? "" : values[1]); + strcat(parameters, "\""); + strcat(parameters, ":"); + + char * item_rev_value = NULL; + TCGetPropertyValue(attachments[i], "Revision", values[0], &item_rev_value); + if (strcmp(values[1], "FACTORYNAME") == 0) + { + item_rev_value = factoryValues[j]; + } + if (strcmp(values[1], "INPUTTIME") == 0) + { + item_rev_value = date; + } + if (strcmp(values[1], "VELOCITYOFVIBRATION") == 0) + { + char * zdjsd = NULL; + char * zdsd = NULL; + TCGetPropertyValue(attachments[i], "Revision", "class.110629", &zdjsd); + TCGetPropertyValue(attachments[i], "Revision", "class.110630", &zdsd); + + + if (zdjsd == NULL) + { + zdjsd = ""; + } + + if (zdsd == NULL) + { + zdsd = ""; + } + + if (strcmp(zdjsd, "") == 0) + { + zdjsd = ""; + } + if (strcmp(zdsd, "") == 0) + { + zdsd = ""; + } + + if (zdjsd != NULL && strcmp(zdjsd, "") != 0 && strstr(zdjsd, ":") != NULL) + { + + int TOLERANCE4Num = 0; + char ** TOLERANCE4values = new char *[64]; + //ַָ + split(zdjsd, ":", TOLERANCE4values, &TOLERANCE4Num); + zdjsd = TOLERANCE4values[0]; + } + + if (zdsd != NULL && strcmp(zdsd, "") != 0 && strstr(zdsd, ":") != NULL) + { + + int TOLERANCE4Num = 0; + char ** TOLERANCE4values = new char *[64]; + //ַָ + split(zdsd, ":", TOLERANCE4values, &TOLERANCE4Num); + zdsd = TOLERANCE4values[0]; + } + + char revValue[256] = ""; + + strcat(revValue, zdjsd); + strcat(revValue, zdsd); + item_rev_value = revValue; + + /*if (zdjsd != NULL && strcmp(zdjsd, "") != 0 && zdsd != NULL && strcmp(zdsd, "") != 0) + { + if (strcmp(zdjsd, "") == 0) + { + zdjsd = ""; + } + if (strcmp(zdsd, "") == 0) + { + zdsd = ""; + } + char revValue[256] = ""; + + strcat(revValue, zdjsd); + strcat(revValue, zdsd); + item_rev_value = revValue; + }*/ + } + if (strcmp(values[1], "TOLERANCE") == 0) + { + char * TOLERANCE1 = NULL; + char * TOLERANCE2 = NULL; + char * TOLERANCE3 = NULL; + char * TOLERANCE4 = NULL; + TCGetPropertyValue(attachments[i], "Revision", "class.110622", &TOLERANCE1); + TCGetPropertyValue(attachments[i], "Revision", "class.112405", &TOLERANCE2); + TCGetPropertyValue(attachments[i], "Revision", "class.112606", &TOLERANCE3); + TCGetPropertyValue(attachments[i], "Revision", "class.110313", &TOLERANCE4); + if (TOLERANCE1 != NULL && strcmp(TOLERANCE1, "") != 0) + { + item_rev_value = TOLERANCE1; + } + if (TOLERANCE2 != NULL && strcmp(TOLERANCE2, "") != 0) + { + item_rev_value = TOLERANCE2; + } + if (TOLERANCE3 != NULL && strcmp(TOLERANCE3, "") != 0) + { + item_rev_value = TOLERANCE3; + } + if (TOLERANCE4 != NULL && strcmp(TOLERANCE4, "") != 0) + { + item_rev_value = TOLERANCE4; + } + if (item_rev_value != NULL && strcmp(item_rev_value, "") != 0 && strstr(item_rev_value,":") != NULL) + { + + int TOLERANCE4Num = 0; + char ** TOLERANCE4values = new char *[64]; + //ַָ + split(item_rev_value, ":", TOLERANCE4values, &TOLERANCE4Num); + item_rev_value = TOLERANCE4values[0]; + } + + + if (strcmp(item_rev_value, "") == 0) + { + item_rev_value = ""; + } + } + if (strcmp(values[1], "FIGURE") == 0) + { + string resultString = item_rev_value; + if (strstr(item_rev_value, "SF-") != NULL) + { + resultString = replace_all_distinct(item_rev_value, "SF-", ""); + } + else if (strstr(item_rev_value, "XX-") != NULL) + { + resultString = replace_all_distinct(item_rev_value, "XX-", ""); + } + char resultChar[256] = ""; + + strcpy(resultChar, resultString.c_str()); + + *(resultChar + strlen(resultString.c_str())) = '\0'; + + item_rev_value = resultChar; + } + + + if (strstr(item_rev_value, "\\") != NULL) + { + string resultString = replace_all_distinct(item_rev_value, "\\", "&&"); + + char resultChar[256] = ""; + + strcpy(resultChar, resultString.c_str()); + + *(resultChar + strlen(resultString.c_str())) = '\0'; + + item_rev_value = resultChar; + + } + + if (strcmp(item_rev_value, "/") == 0) + { + item_rev_value = ""; + } + strcat(parameters, "\""); + strcat(parameters, item_rev_value); + strcat(parameters, "\""); + if (k < valueCount - 1) + { + strcat(parameters, ","); + } + //printf("ַ%s\n", parameters); + + DOFREE(item_rev_value); + } + //printf("parameters%s\n", parameters); + } + valueChar = NULL; + } + else + { + //-в֡ + int valueCount = 0; + char ** valueChar = new char *[64]; + //ַָ + split(name, "=", valueChar, &valueCount); + + strcat(parameters, "\""); + strcat(parameters, valueChar[1] == NULL || strlen(valueChar[1]) == 0 ? "" : valueChar[1]); + strcat(parameters, "\""); + strcat(parameters, ":"); + + char * item_rev_value = NULL; + TCGetPropertyValue(attachments[i], "Revision", valueChar[0], &item_rev_value); + + if (strcmp(valueChar[1], "FACTORYNAME") == 0) + { + item_rev_value = factoryValues[j]; + } + if (strcmp(valueChar[1], "INPUTTIME") == 0) + { + item_rev_value = date; + } + if (strcmp(valueChar[1], "VELOCITYOFVIBRATION") == 0) + { + char * zdjsd = NULL; + char * zdsd = NULL; + TCGetPropertyValue(attachments[i], "Revision", "class.110629", &zdjsd); + TCGetPropertyValue(attachments[i], "Revision", "class.110630", &zdsd); + + + if (zdjsd == NULL) + { + zdjsd = ""; + } + + if (zdsd == NULL) + { + zdsd = ""; + } + + if (strcmp(zdjsd, "") == 0) + { + zdjsd = ""; + } + if (strcmp(zdsd, "") == 0) + { + zdsd = ""; + } + + + if (zdjsd != NULL && strcmp(zdjsd, "") != 0 && strstr(zdjsd, ":") != NULL) + { + + int TOLERANCE4Num = 0; + char ** TOLERANCE4values = new char *[64]; + //ַָ + split(zdjsd, ":", TOLERANCE4values, &TOLERANCE4Num); + zdjsd = TOLERANCE4values[0]; + } + + if (zdsd != NULL && strcmp(zdsd, "") != 0 && strstr(zdsd, ":") != NULL) + { + + int TOLERANCE4Num = 0; + char ** TOLERANCE4values = new char *[64]; + //ַָ + split(zdsd, ":", TOLERANCE4values, &TOLERANCE4Num); + zdsd = TOLERANCE4values[0]; + } + + char revValue[256] = ""; + + strcat(revValue, zdjsd); + strcat(revValue, zdsd); + item_rev_value = revValue; + + /*if (zdjsd != NULL && strcmp(zdjsd, "") != 0 && zdsd != NULL && strcmp(zdsd, "") != 0) + { + if (strcmp(zdjsd, "") == 0) + { + zdjsd = ""; + } + if (strcmp(zdsd, "") == 0) + { + zdsd = ""; + } + char revValue[256] = ""; + + strcat(revValue, zdjsd); + strcat(revValue, zdsd); + item_rev_value = revValue; + }*/ + + + } + if (strcmp(valueChar[1], "TOLERANCE") == 0) + { + char * TOLERANCE1 = NULL; + char * TOLERANCE2 = NULL; + char * TOLERANCE3 = NULL; + char * TOLERANCE4 = NULL; + TCGetPropertyValue(attachments[i], "Revision", "class.110622", &TOLERANCE1); + TCGetPropertyValue(attachments[i], "Revision", "class.112405", &TOLERANCE2); + TCGetPropertyValue(attachments[i], "Revision", "class.112606", &TOLERANCE3); + TCGetPropertyValue(attachments[i], "Revision", "class.110313", &TOLERANCE4); + if (TOLERANCE1 != NULL && strcmp(TOLERANCE1, "") != 0) + { + item_rev_value = TOLERANCE1; + } + if (TOLERANCE2 != NULL && strcmp(TOLERANCE2, "") != 0) + { + item_rev_value = TOLERANCE2; + } + if (TOLERANCE3 != NULL && strcmp(TOLERANCE3, "") != 0) + { + item_rev_value = TOLERANCE3; + } + if (TOLERANCE4 != NULL && strcmp(TOLERANCE4, "") != 0) + { + item_rev_value = TOLERANCE4; + } + if (item_rev_value != NULL && strcmp(item_rev_value, "") != 0 && strstr(item_rev_value, ":") != NULL) + { + + int TOLERANCE4Num = 0; + char ** TOLERANCE4values = new char *[64]; + //ַָ + split(item_rev_value, ":", TOLERANCE4values, &TOLERANCE4Num); + item_rev_value = TOLERANCE4values[0]; + } + } + if (strcmp(valueChar[1], "FIGURE") == 0) + { + string resultString = item_rev_value; + if (strstr(item_rev_value, "SF-") != NULL) + { + resultString = replace_all_distinct(item_rev_value, "SF-", ""); + } + else if (strstr(item_rev_value, "XX-") != NULL) + { + resultString = replace_all_distinct(item_rev_value, "XX-", ""); + } + char resultChar[256] = ""; + + strcpy(resultChar, resultString.c_str()); + + *(resultChar + strlen(resultString.c_str())) = '\0'; + + item_rev_value = resultChar; + } + + + if (strstr(item_rev_value, "\\") != NULL) + { + string resultString = replace_all_distinct(item_rev_value, "\\", "&&"); + + char resultChar[256] = ""; + + strcpy(resultChar, resultString.c_str()); + + *(resultChar + strlen(resultString.c_str())) = '\0'; + + item_rev_value = resultChar; + + } + + if (strcmp(item_rev_value, "/") == 0) + { + item_rev_value = ""; + } + + strcat(parameters, "\""); + strcat(parameters, item_rev_value); + strcat(parameters, "\""); + DOFREE(item_rev_value); + valueChar = NULL; + } + + strcat(parameters, "}"); + } + } + DOFREE(constName); + name = NULL; + + } + + DOFREE(itemType); + strcat(parameters, "]"); + + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + //strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp.jar"); + strcat(cmd, "\" "); + // + cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + //strcat(cmd,"@"); + //strcat(cmd,handler_name); + printf("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE *pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + + strResult = strResult.substr(0, iSize - 1); + printf("·ʧ\n"); + cout << strResult << endl; + if (strcmp(messageResult, "1") == 0) + { + ifail = 1; + } + } + } + messageUserValues.clear(); + vector().swap(messageUserValues); + MEM_free(attachments); + tc_root_file = NULL; + pref_vals = NULL; + if (ifail == 1) + { + //EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, strResult.c_str()); + } + printf("=========================·ERP End===================\n"); + return ifail; +} + + + +//int RB_SendErpItem_New(EPM_action_message_t msg) +//{ +// printf("=========================·ERP Start===================\n"); +// //POM_AM__set_application_bypass(true); +// int ifail = ITK_ok; +// int attachments_num = 0; +// tag_t rootTask = NULLTAG, * attachments = NULLTAG; +// //ȡ +// EPM_ask_root_task(msg.task, &rootTask); +// //ȡĿ +// EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); +// int pref_cnt = 0; +// char** pref_vals = NULL; +// //ȡѡֵ +// PREF_ask_char_values("RB_ItemSendErp_Type_Attr", &pref_cnt, &pref_vals); +// map> itemTypeMap; +// map typePropertyType; +// for (int i = 0; i < pref_cnt; i++) +// { +// if (strstr(pref_vals[i], ":") != NULL) +// { +// //-в֡ +// int valueCount = 0; +// char** valueChar = new char* [64]; +// //ַָ +// split(pref_vals[i], ":", valueChar, &valueCount); +// if (strstr(valueChar[1], "|") != NULL) +// { +// int attrCount = 0; +// char** attrChar = new char* [128]; +// //ַָ +// split(valueChar[1], "|", attrChar, &attrCount); +// for (int j = 0; j < attrCount; j++) +// { +// if (strstr(attrChar[j], "=") != NULL) +// { +// int count = 0; +// char** attrs = new char* [64]; +// //ַָ +// split(attrChar[j], "=", attrs, &count); +// typePropertyType[attrs[0]] = attrs[1]; +// DOFREE(attrs); +// } +// } +// DOFREE(attrChar); +// } +// itemTypeMap[valueChar[0]] = typePropertyType; +// typePropertyType.clear(); +// DOFREE(valueChar); +// +// } +// } +// int unit_pref_cnt = 0; +// char** unit_pref_vals = NULL; +// //ȡѡֵ +// PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); +// map unitMap; +// for (int i = 0; i < unit_pref_cnt; i++) +// { +// if (strstr(unit_pref_vals[i], "=") != NULL) +// { +// //-в֡ +// int valueCount = 0; +// char** valueChar = new char* [64]; +// //ַָ +// split(unit_pref_vals[i], "=", valueChar, &valueCount); +// unitMap[valueChar[0]] = valueChar[1]; +// DOFREE(valueChar); +// } +// } +// int smzq_pref_cnt = 0; +// char** smzq_pref_vals = NULL; +// //ȡѡֵ +// PREF_ask_char_values("RB3_WL_SMZQ", &smzq_pref_cnt, &smzq_pref_vals); +// map smzqMap; +// for (int i = 0; i < smzq_pref_cnt; i++) +// { +// if (strstr(smzq_pref_vals[i], "=") != NULL) +// { +// //-в֡ +// int valueCount = 0; +// char** valueChar = new char* [64]; +// //ַָ +// split(smzq_pref_vals[i], "=", valueChar, &valueCount); +// smzqMap[valueChar[0]] = valueChar[1]; +// DOFREE(valueChar); +// } +// } +// int c_sql_value_count = 0; +// char** c_sql_values; +// ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); +// if (c_sql_value_count != 3) +// { +// printf("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); +// return 1; +// } +// +// char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 +// //+++ +// char parameters[100000] = "";//д뵽ļֵ +// strcat(parameters, "["); +// //ȡǰʱ +// time_t now = time(0); +// tm* p = localtime(&now); +// char date[128] = ""; +// sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); +// +// //"tc11","infodba","//172.16.50.40/tc11" "TC12","infodba","172.16.68.13/tc1" +// int status = ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]); +// printf("status%d\n", status); +// map> classMap; +// for (int i = 0; i < attachments_num; i++) +// { +// char* itemType = NULL; +// AOM_ask_value_string(attachments[i], "object_type", &itemType); +// printf("itemType%s\n", itemType); +// //˵ǰ汾Ķ +// if ((strstr(itemType, "Revision") == NULL) || (strstr(itemType, "Master") != NULL) +// || (strstr(itemType, "master") != NULL) || (strstr(itemType, "BOM") != NULL) || (strstr(itemType, "bom") != NULL) || (strstr(itemType, "Bom") != NULL)) +// { +// DOFREE(itemType); +// continue; +// } +// if (itemTypeMap.find(itemType) != itemTypeMap.end()) { +// map propMap = itemTypeMap[itemType]; +// if (strstr(parameters, "[{") != NULL) { +// strcat(parameters, ","); +// } +// strcat(parameters, "{"); +// //ɹĬֵݶΪ +// strcat(parameters, "\"purchaseClassCode\":\"\","); +// tag_t ico_tag = NULLTAG; +// char* classId = NULL; +// map attrMap; +// ICS_ask_classification_object(attachments[i], &ico_tag); +// if (ico_tag != NULLTAG) { +// ICS_ico_ask_class(ico_tag, &classId); +// printf(">> classId: %s\n", classId); +// //ƶӦid map洢 +// if (classMap.find(classId) == classMap.end()) { +// int count = 0; +// int* ids; +// int* arraySize; +// int* formats; +// int* options; +// char** names; +// char** shortNames; +// char** annotations; +// char** unit; +// char** minValues; +// char** maxValues; +// char** defaultValues; +// char** descriptions; +// ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, +// &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); +// for (int i = 0; i < count; i++) +// { +// attrMap.insert(pair(names[i], ids[i])); +// } +// classMap.insert(pair>(classId, attrMap)); +// if (ids != NULL) { +// DOFREE(ids); +// } +// if (arraySize != NULL) { +// DOFREE(arraySize); +// } +// if (formats != NULL) { +// DOFREE(formats); +// } +// if (options != NULL) { +// DOFREE(options); +// } +// if (names != NULL) { +// DOFREE(names); +// } +// if (shortNames != NULL) { +// DOFREE(shortNames); +// } +// if (annotations != NULL) { +// DOFREE(annotations); +// } +// if (unit != NULL) { +// DOFREE(unit); +// } +// if (minValues != NULL) { +// DOFREE(minValues); +// } +// if (maxValues != NULL) { +// DOFREE(maxValues); +// } +// if (defaultValues != NULL) { +// DOFREE(defaultValues); +// } +// if (descriptions != NULL) { +// DOFREE(descriptions); +// } +// } +// else { +// attrMap = classMap[classId]; +// } +// } +// +// char* classCode = NULL; +// char* className = NULL; +// char* organization = NULL; +// char* punit = NULL; +// char factoryCode[2048] = "\0"; +// //д,ʵ(ͬ) +// if (status) +// { +// printf("ʾ:мݱʧ\n"); +// } +// else { +// char* field1 = NULL; +// char* field2 = NULL; +// int outputColumn = 0, outputValueCount = 0; +// char*** outputValue = NULL; +// printf("ʾ:мݱʳɹ\n"); +// //Ϸ⴦,ͨݿƥ +// char sql[128] = "\0"; +// if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0) { +// if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); +// char* value = NULL; +// ICS_ask_attribute_value(ico_tag, "", &value); +// if (value != NULL) { +// int id = attrMap[""]; +// getClassValue(value, id, &field2); +// DOFREE(value); +// } +// } +// else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) +// { +// char* value = NULL; +// ICS_ask_attribute_value(ico_tag, "Ʒ", &value); +// if (value != NULL) { +// int id = attrMap["Ʒ"]; +// getClassValue(value, id, &field1); +// DOFREE(value); +// } +// ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field2)); +// } +// else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); +// char* value = NULL; +// ICS_ask_attribute_value(ico_tag, "Ʒ", &value); +// if (value != NULL) { +// int id = attrMap["Ʒ"]; +// getClassValue(value, id, &field2); +// DOFREE(value); +// } +// } +// else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) +// { +// char* new_classId = NULL; +// if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) +// { +// new_classId = getFirstStr(classId, 2); +// } +// else +// { +// new_classId = getFirstStr(classId, 4); +// } +// tag_t classTag = NULLTAG; +// char* id = NULL; +// if (new_classId != NULL) { +// ITKCALL(ICS_find_class(new_classId, &classTag)); +// if (classTag != NULLTAG) +// { +// ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); +// } +// } +// if (id != NULL) { +// DOFREE(id); +// } +// if (classTag != NULL) { +// DOFREE(classTag); +// } +// if (new_classId != NULL) { +// DOFREE(new_classId); +// } +// } +// if (field1 != NULL) { +// if (field1 != NULL && field2 != NULL) { +// sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s' and PFIELD02= '%s'", field1, field2); +// } +// else { +// sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); +// } +// } +// } +// else { +// if (strcmp("RB3_ZCRevision", itemType) == 0) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_zclx", &field1)); +// } +// else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 +// || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 +// || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 +// || strcmp("RB3_GZBJRevision", itemType) == 0) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); +// } +// else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0 +// || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); +// } +// else if (strcmp("RB3_XZCPRevision", itemType) == 0) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_cplx2", &field1)); +// } +// else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) +// { +// char* value = NULL; +// ICS_ask_attribute_value(ico_tag, "", &value); +// if (value != NULL) { +// int id = attrMap[""]; +// getClassValue(value, id, &field1); +// DOFREE(value); +// } +// } +// if (field1 != NULL) { +// sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); +// } +// } +// if (strcmp("", sql) != 0) { +// printf("ʾ:sql==%s\n", sql); +// if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) +// { +// printf("ʾ:Ϸѯ ʧ, %s \n", sql); +// char sql2[1024] = "\0"; +// sprintf(sql2, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PFIELD01= '%s'", field1); +// if (QuerySQLNoInputParam(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) +// { +// printf("ʾ:Ϸѯ ʧ, %s \n", sql2); +// } +// } +// printf("outputValueCount=%d\n", outputValueCount); +// printf("outputColumn=%d\n", outputColumn); +// //free(sql); +// if (outputValueCount > 0) { +// classCode = outputValue[0][0]; +// className = outputValue[0][1]; +// organization = outputValue[0][2]; +// punit = outputValue[0][3]; +// printf("Ϸ====%s\n", classCode); +// printf("====%s\n", className); +// printf("֯====%s\n", organization); +// printf("λ====%s\n", punit); +// } +// } +// //ɹ⴦,ͨݿƥ +// // +// // +// //֯⴦,ͨݿƥ +// char** factorys = NULL; +// int factoryCount = 0; +// if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { +// ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_xzscgc", &factoryCount, &factorys)); +// } +// else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 +// || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { +// ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc", &factoryCount, &factorys)); +// } +// else if (strcmp("RB3_YCLRevision", itemType) == 0) { +// ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_sygc1", &factoryCount, &factorys)); +// } +// else { +// ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc1", &factoryCount, &factorys)); +// } +// printf("factoryCount=%d\n", factoryCount); +// for (int j = 0; j < factoryCount; j++) +// { +// char*** factoryValue = NULL; +// int factoryColumn = 0, factoryValueCount = 0; +// char factorySql[128] = "\0"; +// printf("factorys[j]==%s\n", factorys[j]); +// sprintf(factorySql, "select PFACTORYCODE from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", factorys[j]); +// printf("ʾ:factorySql==%s\n", factorySql); +// if (QuerySQLNoInputParam(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) +// { +// printf("ʾ:֯ѯ ʧ, %s \n", factorySql); +// } +// printf("factoryValueCount=%d\n", factoryValueCount); +// printf("factoryColumn=%d\n", factoryColumn); +// //free(sql); +// if (factoryValueCount > 0) { +// if (strcmp("", factoryCode) != 0) { +// strcat(factoryCode, ","); +// } +// strcat(factoryCode, factoryValue[0][0]); +// printf("֯====%s\n", factoryCode); +// } +// if (factoryValue != NULL) { +// DOFREE(factoryValue); +// } +// } +// +// if (factorys != NULL) { +// DOFREE(factorys); +// } +// if (outputValue != NULL) { +// DOFREE(outputValue); +// } +// if (field1 != NULL) { +// DOFREE(field1); +// } +// if (field2 != NULL) { +// DOFREE(field2); +// } +// } +// if (factoryCode != NULL) { +// strcat(parameters, "\"orgCode\":\""); +// strcat(parameters, factoryCode); +// if (organization != NULL) { +// strcat(parameters, ","); +// strcat(parameters, organization); +// } +// strcat(parameters, "\","); +// } +// strcat(parameters, "\"manageClassCode\":\""); +// if (classCode != NULL) { +// strcat(parameters, classCode); +// } +// strcat(parameters, "\","); +// // ʹõmap +// int index = 0; +// for (std::map::iterator it = propMap.begin(); it != propMap.end(); ++it) { +// string key = it->first; +// string attr = it->second; +// printf("key: %s \n", key.c_str()); +// printf("attr: %s \n", attr.c_str()); +// if (strcmp("orgCode", key.c_str()) == 0) { +// index++; +// continue; +// } +// if (strstr(attr.c_str(), ".") != NULL) +// { +// int attrCount = 0; +// char** attrChar = new char* [128]; +// char* attrName = new char[2048];//㹻 +// strcpy(attrName, attr.c_str()); +// printf("attrName: %s \n", attrName); +// //ַָ +// split(attrName, ".", attrChar, &attrCount); +// char* value = NULL; +// if (strcmp("rev", attrChar[0]) == 0) { +// //λ⴦ +// if (strcmp("uom_tag", attrChar[1]) == 0) +// { +// tag_t item = NULLTAG; +// ITKCALL(ITEM_ask_item_of_rev(attachments[i], &item)); +// tag_t unitTag = NULLTAG; +// ITKCALL(AOM_ask_value_tag(item, attrChar[1], &unitTag)); +// if (unitTag != NULL) { +// ITKCALL(AOM_UIF_ask_value(unitTag, "object_string", &value)); +// printf("uom_tag: %s \n", value); +// //λ +// // ضϷ൥λ㣺λLתWL֬ļλGM() תKGǧˣ;ֲģֹܼλGM()תT֣ +// if (className != NULL) { +// if (strcmp("", className) == 0 && strcmp("L()", value) == 0) +// { +// value = "WL()"; +// } +// else if (strcmp("֬", className) == 0 && strcmp("GM()", value) == 0) +// { +// value = "KG(ǧ)"; +// }if ((strcmp("ֲ", className) == 0 || strcmp("ֹ", className) == 0) && strcmp("GM()", value) == 0) +// { +// value = "T()"; +// } +// } +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// if (unitMap.find(value) != unitMap.end()) { +// strcat(parameters, unitMap[value].c_str()); +// } +// else { +// strcat(parameters, value); +// } +// strcat(parameters, "\""); +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// if (punit != NULL) { +// strcat(parameters, punit); +// } +// strcat(parameters, "\""); +// +// } +// if (item != NULL) { +// DOFREE(item); +// } +// if (unitTag != NULL) { +// DOFREE(unitTag); +// } +// +// } +// //⴦ +// else if (strcmp("netWeight", key.c_str()) == 0) +// { +// strcat(parameters, "\"netWeightUnitCode\":\"KG\","); +// ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); +// if (value != NULL && strcmp("", value) != 0) { +// double dValue = std::stod(value); +// dValue = dValue * 10000; +// long lValue = static_cast(dValue); // תΪlong +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":"); +// char netWeight[64] = "\0"; +// sprintf(netWeight, "%d", lValue); +// strcat(parameters, netWeight); +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":0"); +// } +// } +// //⴦ +// else if (strcmp("material_status", key.c_str()) == 0) +// { +// ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// if (smzqMap.find(value) != smzqMap.end()) { +// strcat(parameters, smzqMap[value].c_str()); +// } +// else { +// strcat(parameters, value); +// } +// strcat(parameters, "\""); +// } +// else { +// ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// strcat(parameters, value); +// strcat(parameters, "\""); +// } +// } +// else { +// if (ico_tag != NULLTAG) { +// if (strstr(attrChar[1], "&") != NULL) +// { +// int attrNum = 0; +// char** allAttrs = new char* [128]; +// //ַָ +// split(attrChar[1], "&", allAttrs, &attrNum); +// char values[256] = "";//ƴ +// for (int i = 0; i < attrNum; i++) +// { +// if (attrMap.find(allAttrs[i]) != attrMap.end()) +// { +// ICS_ask_attribute_value(ico_tag, allAttrs[i], &value); +// DOFREE(disValue); +// if (value != NULL) { +// int id = attrMap[allAttrs[i]]; +// char* disValue; +// getClassValue(value, id, &disValue); +// strcat(values, disValue); +// DOFREE(disValue); +// } +// else { +// strcat(values, ""); +// } +// } +// else { +// strcat(values, ""); +// } +// } +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// strcat(parameters, values); +// strcat(parameters, "\""); +// DOFREE(allAttrs); +// } +// else { +// //ּܰ⴦ +// if (strcmp("CU0261", key.c_str()) == 0) +// { +// if (attrMap.find("ּܰ(mm)") != attrMap.end()) +// { +// attrChar[1] = "ּܰ(mm)"; +// } +// else if (attrMap.find("ѹּܰ(mm)") != attrMap.end()) +// { +// attrChar[1] = "ѹּܰ(mm)"; +// } +// else if (attrMap.find("ּܰ()") != attrMap.end()) +// { +// attrChar[1] = "ּܰ()"; +// } +// } +// //ܷɫ⴦ +// else if (strcmp("CU0262", key.c_str()) == 0) +// { +// if (attrMap.find("ܷɫ") != attrMap.end()) +// { +// //printf("1111\n"); +// attrChar[1] = "ܷɫ"; +// } +// else if (attrMap.find("ܷɫ(ֶ)") != attrMap.end()) +// { +// attrChar[1] = "ܷɫ(ֶ)"; +// } +// else if (attrMap.find("(ܷɫ)") != attrMap.end()) +// { +// attrChar[1] = "(ܷɫ)"; +// } +// } +// //ܷ⴦ +// else if (strcmp("CU0263", key.c_str()) == 0) +// { +// if (attrMap.find("ܷ") != attrMap.end()) +// { +// //printf("2222\n"); +// attrChar[1] = "ܷ"; +// } +// else if (attrMap.find("ܷ(ֶ)") != attrMap.end()) +// { +// attrChar[1] = "ܷ(ֶ)"; +// } +// else if (attrMap.find("(ܷ)") != attrMap.end()) +// { +// attrChar[1] = "(ܷ)"; +// } +// } +// //printf("attrChar[1] = %s \n", attrChar[1]); +// if (attrMap.find(attrChar[1]) != attrMap.end()) +// { +// ICS_ask_attribute_value(ico_tag, attrChar[1], &value); +// if (value != NULL && strcmp(value,"") != 0 && strcmp(value, " ") != 0) { +// int id = attrMap[attrChar[1]]; +// char* disValue; +// getClassValue(value, id, &disValue); +// /* printf("id = %d \n", id); +// printf("disValue = %s \n", disValue);*/ +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// strcat(parameters, disValue); +// strcat(parameters, "\""); +// DOFREE(disValue); +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// } +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// } +// printf("value: %s \n", value); +// DOFREE(value); +// DOFREE(attrChar); +// DOFREE(attrName); +// } +// else { +// if (strcmp("CU0266", key.c_str()) == 0 && strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) +// { +// printf("㲿⴦\n"); +// char* value = NULL; +// if (attrMap.find("") != attrMap.end()) +// { +// printf(" : %s \n", value); +// ICS_ask_attribute_value(ico_tag, "", &value); +// if (value != NULL) { +// int id = attrMap[""]; +// char* disValue; +// getClassValue(value, id, &disValue); +// printf("disValue : %s \n", disValue); +// if (strcmp("C:", disValue) == 0) { +// tag_t parentClass = NULLTAG; +// char* parentClassId = NULL; +// char* parentClassName = NULL; +// ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); +// if (parentClass != NULLTAG) { +// ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\""); +// strcat(parameters, parentClassName); +// strcat(parameters, "\""); +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// DOFREE(parentClass); +// DOFREE(parentClassId); +// DOFREE(parentClassName); +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// DOFREE(disValue); +// } +// else { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// } +// else +// { +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// DOFREE(value); +// }//⴦ +// else if (strcmp("netWeight", key.c_str()) == 0) +// { +// strcat(parameters, "\"netWeightUnitCode\":\"KG\","); +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":0"); +// } +// else +// { +// printf("key: %s ĬΪֵ\n", key.c_str()); +// strcat(parameters, "\""); +// strcat(parameters, key.c_str()); +// strcat(parameters, "\":\"\""); +// } +// } +// if (index < propMap.size() - 1) +// { +// strcat(parameters, ","); +// } +// if (classId != NULL) { +// DOFREE(classId); +// } +// if (ico_tag != NULL) { +// DOFREE(ico_tag); +// } +// if (classCode != NULL) { +// DOFREE(classCode); +// } +// if (className != NULL) { +// DOFREE(className); +// } +// if (organization != NULL) { +// DOFREE(organization); +// } +// if (punit != NULL) { +// DOFREE(punit); +// } +// index++; +// } +// strcat(parameters, "}"); +// attrMap.clear(); +// } +// DOFREE(itemType); +// } +// DisConnServer(); +// strcat(parameters, "]"); +// //printf("parameters: %s\n", parameters); +// //дļ +// char data_file[SS_MAXPATHLEN] = ""; +// strcat(data_file, tc_root_file); +// strcat(data_file, "\\"); +// strcat(data_file, date); +// strcat(data_file, ".txt"); +// printf("data_file: %s\n", data_file); +// ofstream file; +// file.open(data_file); +// file << parameters << endl; // ʹcoutͬķʽд +// file.close(); +// +// string strResult; +// +// //cmdָ +// char cmd[256] = ""; +// strcpy(cmd, "java -jar \""); +// strcat(cmd, tc_root_file); +// strcat(cmd, "\\portal\\plugins\\"); +// strcat(cmd, "RB_SendErp_New.jar"); +// strcat(cmd, "\" "); +// // +// //cout << data_file << endl; +// strcat(cmd, data_file); +// //ݱ̵(@ָ) +// strcat(cmd, "@WL"); +// //printf("·:\n%s\n", cmd); +// char buf[8000] = { 0 }; +// FILE* pf = NULL; +// if ((pf = _popen(cmd, "r")) == NULL) { +// printf("ӿڷ:\n%s", "1"); +// } +// +// while (fgets(buf, sizeof buf, pf)) { +// strResult += buf; +// } +// _pclose(pf); +// +// cout << strResult << endl; +// unsigned int iSize = strResult.size(); +// if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) +// { +// +// strResult = strResult.substr(0, iSize - 1); +// printf("·ʧ\n"); +// cout << strResult << endl; +// } +// printf("ifail: %d\n", ifail); +// if (attachments != NULL) { +// MEM_free(attachments); +// } +// if (pref_vals != NULL) { +// MEM_free(pref_vals); +// } +// //if (tc_root_file != NULL) { +// // MEM_free(tc_root_file); +// //} +// printf("=========================·ERP End===================\n"); +// return ifail; +//} + +int RB_SendErpItem_New(EPM_action_message_t msg) +{ + printf("=========================·ERP Start===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + int pref_cnt = 0; + char** pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_ItemSendErp_Type_Attr", &pref_cnt, &pref_vals); + map> itemTypeMap; + map typePropertyType; + for (int i = 0; i < pref_cnt; i++) + { + if (strstr(pref_vals[i], ":") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(pref_vals[i], ":", valueChar, &valueCount); + if (strstr(valueChar[1], "|") != NULL) + { + int attrCount = 0; + char** attrChar = new char* [128]; + //ַָ + split(valueChar[1], "|", attrChar, &attrCount); + for (int j = 0; j < attrCount; j++) + { + if (strstr(attrChar[j], "=") != NULL) + { + int count = 0; + char** attrs = new char* [64]; + //ַָ + split(attrChar[j], "=", attrs, &count); + typePropertyType[attrs[0]] = attrs[1]; + DOFREE(attrs); + } + } + DOFREE(attrChar); + } + itemTypeMap[valueChar[0]] = typePropertyType; + typePropertyType.clear(); + DOFREE(valueChar); + + } + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int smzq_pref_cnt = 0; + char** smzq_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB3_WL_SMZQ", &smzq_pref_cnt, &smzq_pref_vals); + map smzqMap; + for (int i = 0; i < smzq_pref_cnt; i++) + { + if (strstr(smzq_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(smzq_pref_vals[i], "=", valueChar, &valueCount); + smzqMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + printf("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + return 1; + } + + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + //+++ + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "["); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //"tc11","infodba","//172.16.50.40/tc11" "TC12","infodba","172.16.68.13/tc1" + int status = ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + printf("status%d\n", status); + map> classMap; + for (int i = 0; i < attachments_num; i++) + { + char* itemType = NULL; + char* itemId1 = NULL; + AOM_ask_value_string(attachments[i], "item_id", &itemId1); + AOM_ask_value_string(attachments[i], "object_type", &itemType); + printf("itemType%s\n", itemType); + printf("itemId1%s\n", itemId1); + DOFREE(itemId1); + //˵ǰ汾Ķ + if ((strstr(itemType, "Revision") == NULL) || (strstr(itemType, "Master") != NULL) + || (strstr(itemType, "master") != NULL) || (strstr(itemType, "BOM") != NULL) || (strstr(itemType, "bom") != NULL) || (strstr(itemType, "Bom") != NULL)) + { + DOFREE(itemType); + continue; + } + if (itemTypeMap.find(itemType) != itemTypeMap.end()) { + map propMap = itemTypeMap[itemType]; + if (strstr(parameters, "[{") != NULL) { + strcat(parameters, ","); + } + strcat(parameters, "{"); + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(attachments[i], &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + printf(">> classId: %s\n", classId); + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + } + + char* classCode = NULL; + char* cgCode = NULL; + char* className = NULL; + char* organization = NULL; + char* punit = NULL; + char factoryCode[2048] = "\0"; + //д,ʵ(ͬ) + if (status) + { + printf("ʾ:мݱʧ\n"); + } + else { + char* field1 = NULL; + char* field2 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + printf("ʾ:мݱʳɹ\n"); + //Ϸ⴦,ͨݿƥ + char sql[256] = "\0"; + if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 + || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_YCLRevision", itemType) == 0) { + if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field1); + DOFREE(value); + } + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field2)); + } + else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* new_classId = NULL; + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) + { + new_classId = getFirstStr(classId, 2); + } + else + { + new_classId = getFirstStr(classId, 4); + } + tag_t classTag = NULLTAG; + char* id = NULL; + if (new_classId != NULL) { + ITKCALL(ICS_find_class(new_classId, &classTag)); + if (classTag != NULLTAG) + { + ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); + } + } + if (id != NULL) { + DOFREE(id); + } + if (classTag != NULL) { + DOFREE(classTag); + } + if (new_classId != NULL) { + DOFREE(new_classId); + } + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "״", &value); + if (value != NULL) { + int id = attrMap["״"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + if (field1 != NULL) { + if (field1 != NULL && field2 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s' and PFIELD02= '%s'", itemType, field1, field2); + } + else { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + } + } + } + else { + if (strcmp("RB3_ZCRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_zclx", &field1)); + } + else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 + || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 + || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 + || strcmp("RB3_GZBJRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + } + else if (strcmp("RB3_SLRevision", itemType) == 0 + || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); + } + else if (strcmp("RB3_XZCPRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_cplx2", &field1)); + } + else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field1); + DOFREE(value); + } + } + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + } + } + if (strcmp("", sql) != 0) { + printf("ʾ:sql==%s\n", sql); + if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + printf("ʾ:Ϸѯ ʧ, %s \n", sql); + char sql2[256] = "\0"; + sprintf(sql2, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + if (QuerySQLNoInputParam(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) + { + printf("ʾ:Ϸѯ ʧ, %s \n", sql2); + } + } + printf("outputValueCount=%d\n", outputValueCount); + printf("outputColumn=%d\n", outputColumn); + //free(sql); + if (outputValueCount > 0) { + classCode = outputValue[0][0]; + className = outputValue[0][1]; + organization = outputValue[0][2]; + punit = outputValue[0][3]; + printf("Ϸ====%s\n", classCode); + printf("====%s\n", className); + printf("֯====%s\n", organization); + printf("λ====%s\n", punit); + } + } + //ɹ⴦,ͨݿƥ + // + + char* limit_value = NULL; + char* object_name = NULL; + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &object_name)); + char* cgField1 = NULL; + char* cgField2= NULL; + char* cgField3 = NULL; + char cgSql[256] = "\0"; + char cgSql2[256] = "\0"; + if (strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + //ȡobject_name롾ֵֶ2ƥ䣬ȡӦɹ롿д + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, object_name); + } + else if (strcmp("RB3_GQRevision", itemType) == 0) { + /* + ȡֶΡ𡿵ֵ롾ֵֶ2ƥ䣬 + ٻȡֶ3ֵֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + ֵȡ롾ֵֶ3бȶԣȡֵСڵһֵƥ䡾ɹ롿ĵһֵдݣ + ȡֵڵڵһֵСڵڶֵƥ䡾ɹ롿ĵڶֵдݣ + ȡֵڵڵڶֵƥ䡾ɹ롿ĵֵдݣ + */ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE03 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0) { + //ȸݻȡġERPϷࡿƥ䡾ֵֶ1ٸݡֶ2ݻȡǰλorǰλ + //ȡֵ롾ֵֶ2ƥ䣬ӶȡӦɹ롿дݣ + //IN41 IN38 ȡǰ4λ + char* newClassId = NULL; + if (strcmp("IN41", classCode) == 0 || strcmp("IN38", classCode) == 0) { + newClassId = getFirstStr(classId, 4); + } + else { + newClassId = getFirstStr(classId, 6); + } + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE01= '%s' and PFIELDVALUE02= '%s'", + itemType, classCode, newClassId); + } + else if (strcmp("RB3_GZRevision", itemType) == 0) { + /* + ȡӦֶΡֵ͡롾ֵֶ2ƥ䣬ٻȡֶ3ֵ + ֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + ֵȡ롾ֵֶ3бȶ + */ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + AOM_UIF_ask_value(attachments[i], "rb3_gzzj", &cgField3); + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE03 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else if (strcmp("RB3_LBJRevision", itemType) == 0) { + /* + ΪIN04IN03ȡϷ൹ڶ롾ֵֶ2ƥ䣬ٻȡֶ3ֵֶ3Ϊֱƥ䵽Ӧɹ롿дݣֵȡobject_name롾ֵֶ3ƥ䣻ٻȡֶ4ֵֶ4Ϊֱƥ䵽Ӧɹ롿дݣֶ4ֵֶ4ֵȡӦԵֵ롾ֵֶ4ƥȡɹ࣬ȶ߼ֵƥ߼˵ + ΪIN08ֱӻȡֶΡṹԡ롾ֵֶ3ƥ䣬ȡӦɹ롿дݣ + ΪIN09IN24ȡobject_name롾ֵֶ2ƥ䣬ȡӦɹ롿дݣ + */ + + if (strcmp("IN04", classCode) == 0 || strcmp("IN03", classCode) == 0) { + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + if (strstr(object_name, "Ȧ") != NULL || strcmp("Ȧ", object_name) == 0) { + //γߴ_⾶(mm) + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "γߴ_⾶(mm)", &value); + if (value != NULL) { + int id = attrMap["γߴ_⾶(mm)"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + } + else { + // γߴ_ھ(mm) + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "γߴ_ھ(mm)", &value); + if (value != NULL) { + int id = attrMap["γߴ_ھ(mm)"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + } + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s'", + itemType, parentClassName, object_name); + sprintf(cgSql2, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, parentClassName); + } + } + else if (strcmp("IN08", classCode) == 0) { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "ּ", &value); + if (value != NULL) { + printf("value=====%s\n", value); + int id = attrMap["ּ"]; + printf("id=====================%d\n", id); + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "ṹ", &value); + if (value != NULL) { + printf("value=====%s\n", value); + int id = attrMap["ṹ"]; + printf("id=====================%d\n",id); + getClassValue(value, id, &cgField2); + DOFREE(value); + } + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s'", + itemType, cgField1, cgField2); + } + else if (strcmp("IN09", classCode) == 0 || strcmp("IN24", classCode) == 0) { + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, object_name); + } + } + else if (strcmp("RB3_SLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0) { + //ֱӻȡӦɹ롿д + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s'", + itemType); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0) { + //ֱӻȡֶΡ״롾ֵֶ2ƥ䣬ٻȡֶ3ֵ + //ֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + //ֶ3ֵΪϹȡֶΡϹֵ롾ֵֶ3бȶԣ + // ȶ߼ֵƥ߼˵ + //ֶ3ֵΪ;ȡֶΡ;ֵ롾ֵֶ3ƥ䣬 + //ٻȡֶ4ֵֶ4Ϊֱƥ䵽Ӧɹ롿дݣ + //ֶ4ֵֶ4ֵȡӦԵֵ롾ֵֶ4ƥȡɹ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "״", &value); + if (value != NULL) { + int id = attrMap["״"]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, ";", &value); + if (value != NULL) { + int id = attrMap[";"]; + getClassValue(value, id, &cgField2); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "Ϲ", &value); + if (value != NULL) { + int id = attrMap["Ϲ"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + if (strcmp("IN01", classCode) == 0 || strcmp("IN02", classCode) == 0 || strcmp("IN53", classCode) == 0) { + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else { + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s'", + itemType, cgField1, cgField2); + } + } + + int cgOutputColumn = 0, cgOutputValueCount = 0; + + char*** cgOutputValue = NULL; + + if (strcmp("", cgSql) != 0) { + printf("ʾ:cgSql==%s\n", cgSql); + if (QuerySQLNoInputParam(cgSql, &cgOutputColumn, &cgOutputValueCount, &cgOutputValue) == -1 || cgOutputValueCount == 0) + { + if (cgOutputValue != NULL) { + for (int i1 = 0; i1 < cgOutputValueCount;i1 ++) { + for (int i2 = 0; i2 < cgOutputColumn;i2 ++) { + DOFREE(cgOutputValue[i1][i2]); + } + DOFREE(cgOutputValue[i1]); + } + DOFREE(cgOutputValue); + } + printf("I2 => C=%d,R=%d\n", cgOutputColumn, cgOutputValueCount); + cgOutputColumn = 0; + cgOutputValueCount = 0; + printf("ʾ:ɹѯ ʧ, %s \n", cgSql); + if (QuerySQLNoInputParam(cgSql2, &cgOutputColumn, &cgOutputValueCount, &cgOutputValue) == -1) + { + printf("ʾ:ɹѯ ʧ, %s \n", cgSql2); + } + } + printf("cgOutputValueCount=%d\n", cgOutputValueCount); + printf("cgOutputColumn=%d\n", cgOutputColumn); + //free(sql); + if (cgField3 != NULL && (strcmp("IN04", classCode) == 0 || strcmp("IN03", classCode) == 0)) { + printf("111\n"); + char result[32]; // ȷresult㹻Դ洢 + // ڶַλ + size_t second_char_pos = 2; + if (strstr(cgField3, "") != NULL) + { + // ȡڶַ֮ + strcpy(result, cgField3 + second_char_pos); + printf("1\n"); + } + if (strstr(cgField3, "") != NULL) + { + // ȡڶַ֮ + strcpy(result, cgField3 + second_char_pos); + printf("2\n"); + } + printf("cgField3====%s\n", result); + double result_num = atof(result); // תΪ + if (cgOutputValueCount > 0) { + cgCode = cgOutputValue[0][0]; + limit_value = cgOutputValue[0][1]; + printf("ɹ====%s\n", cgCode); + printf("ֵ====%s\n", limit_value); + if (limit_value != NULL + && strcmp(limit_value, "") != 0 + && strcmp(limit_value, " ") != 0) { + if (strstr(limit_value, "-") != NULL) + { + //-в֡ + int numCount = 0; + char** numChar = new char* [64]; + int valCount = 0; + char** valChar = new char* [64]; + //ַָ + split(limit_value, "-", numChar, &numCount); + split(cgCode, ",", valChar, &valCount); + for (int ii = 0; ii < numCount; ii++) + { + double int_value1 = atof(numChar[ii]); + if (result_num < int_value1) { + cgCode = valChar[ii]; + break; + } + else { + if (ii != numCount - 1) { + double int_value2 = atof(numChar[ii + 1]); + if (result_num < int_value2) { + cgCode = valChar[ii + 1]; + break; + } + } + else { + cgCode = valChar[numCount - 1]; + break; + } + } + } + DOFREE(numChar); + } + } + printf("ɹ====%s\n", cgCode); + } + } + else { + printf("222\n"); + if (cgOutputValueCount > 0) { + cgCode = cgOutputValue[0][0]; + } + /*if (true) { + return 0; + }*/ + printf("333\n"); + } + if (object_name != NULL) { + DOFREE(object_name); + } + if (limit_value != NULL) { + DOFREE(limit_value); + } + } + // + //֯⴦,ͨݿƥ + char** factorys = NULL; + int factoryCount = 0; + if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_xzscgc", &factoryCount, &factorys)); + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 + || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc", &factoryCount, &factorys)); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_sygc1", &factoryCount, &factorys)); + } + else { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc1", &factoryCount, &factorys)); + } + printf("factoryCount=%d\n", factoryCount); + for (int j = 0; j < factoryCount; j++) + { + char*** factoryValue = NULL; + int factoryColumn = 0, factoryValueCount = 0; + char factorySql[128] = "\0"; + printf("factorys[j]==%s\n", factorys[j]); + sprintf(factorySql, "select PFACTORYCODE from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", factorys[j]); + printf("ʾ:factorySql==%s\n", factorySql); + if (QuerySQLNoInputParam(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + printf("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + printf("factoryValueCount=%d\n", factoryValueCount); + printf("factoryColumn=%d\n", factoryColumn); + //free(sql); + if (factoryValueCount > 0) { + if (strcmp("", factoryCode) != 0) { + strcat(factoryCode, ","); + } + strcat(factoryCode, factoryValue[0][0]); + printf("֯====%s\n", factoryCode); + } + if (factoryValue != NULL) { + DOFREE(factoryValue); + } + } + + if (factorys != NULL) { + DOFREE(factorys); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + if (cgField1 != NULL) { + DOFREE(cgField1); + } + if (cgField2 != NULL) { + DOFREE(cgField2); + } + if (cgField3 != NULL) { + DOFREE(cgField3); + } + } + if (factoryCode != NULL) { + strcat(parameters, "\"orgCode\":\""); + strcat(parameters, factoryCode); + if (organization != NULL) { + strcat(parameters, ","); + strcat(parameters, organization); + } + strcat(parameters, "\","); + } + strcat(parameters, "\"manageClassCode\":\""); + if (classCode != NULL) { + strcat(parameters, classCode); + } + strcat(parameters, "\","); + strcat(parameters, "\"purchaseClassCode\":\""); + if (cgCode != NULL) { + strcat(parameters, cgCode); + } + strcat(parameters, "\","); + // ʹõmap + int index = 0; + for (std::map::iterator it = propMap.begin(); it != propMap.end(); ++it) { + string key = it->first; + string attr = it->second; + printf("key: %s \n", key.c_str()); + printf("attr: %s \n", attr.c_str()); + if (strcmp("orgCode", key.c_str()) == 0) { + index++; + continue; + } + if (strstr(attr.c_str(), ".") != NULL) + { + int attrCount = 0; + char** attrChar = new char* [128]; + char* attrName = new char[2048];//㹻 + strcpy(attrName, attr.c_str()); + printf("attrName: %s \n", attrName); + //ַָ + split(attrName, ".", attrChar, &attrCount); + char* value = NULL; + if (strcmp("rev", attrChar[0]) == 0) { + //λ⴦ + if (strcmp("uom_tag", attrChar[1]) == 0) + { + tag_t item = NULLTAG; + ITKCALL(ITEM_ask_item_of_rev(attachments[i], &item)); + tag_t unitTag = NULLTAG; + ITKCALL(AOM_ask_value_tag(item, attrChar[1], &unitTag)); + if (unitTag != NULL) { + ITKCALL(AOM_UIF_ask_value(unitTag, "object_string", &value)); + printf("uom_tag: %s \n", value); + //λ + // ضϷ൥λ㣺λLתWL֬ļλGM() תKGǧˣ;ֲģֹܼλGM()תT֣ + if (className != NULL) { + if (strcmp("", className) == 0 && strcmp("L()", value) == 0) + { + value = "WL()"; + } + else if (strcmp("֬", className) == 0 && strcmp("GM()", value) == 0) + { + value = "KG(ǧ)"; + }if ((strcmp("ֲ", className) == 0 || strcmp("ֹ", className) == 0) && strcmp("GM()", value) == 0) + { + value = "T()"; + } + } + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (unitMap.find(value) != unitMap.end()) { + strcat(parameters, unitMap[value].c_str()); + } + else { + strcat(parameters, value); + } + strcat(parameters, "\""); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (punit != NULL) { + strcat(parameters, punit); + } + strcat(parameters, "\""); + + } + if (item != NULL) { + DOFREE(item); + } + if (unitTag != NULL) { + DOFREE(unitTag); + } + + } + //⴦ + else if (strcmp("netWeight", key.c_str()) == 0) + { + strcat(parameters, "\"netWeightUnitCode\":\"KG\","); + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + if (value != NULL && strcmp("", value) != 0) { + double dValue = std::stod(value); + dValue = dValue * 10000; + long lValue = static_cast(dValue); // תΪlong + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":"); + char netWeight[64] = "\0"; + sprintf(netWeight, "%d", lValue); + strcat(parameters, netWeight); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":0"); + } + } + //⴦ + else if (strcmp("material_status", key.c_str()) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (smzqMap.find(value) != smzqMap.end()) { + strcat(parameters, smzqMap[value].c_str()); + } + else { + strcat(parameters, value); + } + strcat(parameters, "\""); + } + else { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, value); + strcat(parameters, "\""); + } + } + else { + if (ico_tag != NULLTAG) { + if (strstr(attrChar[1], "&") != NULL) + { + int attrNum = 0; + char** allAttrs = new char* [128]; + //ַָ + split(attrChar[1], "&", allAttrs, &attrNum); + char values[256] = "";//ƴ + for (int i = 0; i < attrNum; i++) + { + if (attrMap.find(allAttrs[i]) != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, allAttrs[i], &value); + if (value != NULL) { + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + strcat(values, disValue); + DOFREE(disValue); + } + else { + strcat(values, ""); + } + } + else { + strcat(values, ""); + } + } + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, values); + strcat(parameters, "\""); + DOFREE(allAttrs); + } + else { + //ּܰ⴦ + if (strcmp("CU0261", key.c_str()) == 0) + { + if (attrMap.find("ּܰ(mm)") != attrMap.end()) + { + attrChar[1] = "ּܰ(mm)"; + } + else if (attrMap.find("ѹּܰ(mm)") != attrMap.end()) + { + attrChar[1] = "ѹּܰ(mm)"; + } + else if (attrMap.find("ּܰ()") != attrMap.end()) + { + attrChar[1] = "ּܰ()"; + } + } + //ܷɫ⴦ + else if (strcmp("CU0262", key.c_str()) == 0) + { + if (attrMap.find("ܷɫ") != attrMap.end()) + { + //printf("1111\n"); + attrChar[1] = "ܷɫ"; + } + else if (attrMap.find("ܷɫ(ֶ)") != attrMap.end()) + { + attrChar[1] = "ܷɫ(ֶ)"; + } + else if (attrMap.find("(ܷɫ)") != attrMap.end()) + { + attrChar[1] = "(ܷɫ)"; + } + } + //ܷ⴦ + else if (strcmp("CU0263", key.c_str()) == 0) + { + if (attrMap.find("ܷ") != attrMap.end()) + { + //printf("2222\n"); + attrChar[1] = "ܷ"; + } + else if (attrMap.find("ܷ(ֶ)") != attrMap.end()) + { + attrChar[1] = "ܷ(ֶ)"; + } + else if (attrMap.find("(ܷ)") != attrMap.end()) + { + attrChar[1] = "(ܷ)"; + } + } + //printf("attrChar[1] = %s \n", attrChar[1]); + if (attrMap.find(attrChar[1]) != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, attrChar[1], &value); + if (value != NULL && strcmp(value, "") != 0 && strcmp(value, " ") != 0) { + int id = attrMap[attrChar[1]]; + char* disValue; + getClassValue(value, id, &disValue); + /* printf("id = %d \n", id); + printf("disValue = %s \n", disValue);*/ + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, disValue); + strcat(parameters, "\""); + DOFREE(disValue); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + printf("value: %s \n", value); + DOFREE(value); + DOFREE(attrChar); + DOFREE(attrName); + } + else { + if (strcmp("CU0266", key.c_str()) == 0 && strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + printf("㲿⴦\n"); + char* value = NULL; + if (attrMap.find("") != attrMap.end()) + { + printf(" : %s \n", value); + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + char* disValue; + getClassValue(value, id, &disValue); + printf("disValue : %s \n", disValue); + if (strcmp("C:", disValue) == 0) { + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, parentClassName); + strcat(parameters, "\""); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(parentClass); + DOFREE(parentClassId); + DOFREE(parentClassName); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(disValue); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + else + { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(value); + }//⴦ + else if (strcmp("netWeight", key.c_str()) == 0) + { + strcat(parameters, "\"netWeightUnitCode\":\"KG\","); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":0"); + } + else + { + printf("key: %s ĬΪֵ\n", key.c_str()); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + if (index < propMap.size() - 1) + { + strcat(parameters, ","); + } + index++; + } + if (classId != NULL) { + DOFREE(classId); + } + if (ico_tag != NULL) { + DOFREE(ico_tag); + } + if (classCode != NULL) { + DOFREE(classCode); + } + if (cgCode != NULL) { + DOFREE(cgCode); + } + if (className != NULL) { + DOFREE(className); + } + if (organization != NULL) { + DOFREE(organization); + } + if (punit != NULL) { + DOFREE(punit); + } + strcat(parameters, "}"); + attrMap.clear(); + } + DOFREE(itemType); + } + DisConnServer(); + strcat(parameters, "]"); + //printf("parameters: %s\n", parameters); + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + printf("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@WL"); + //printf("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + + strResult = strResult.substr(0, iSize - 1); + printf("·ʧ\n"); + cout << strResult << endl; + } + printf("ifail: %d\n", ifail); + if (attachments != NULL) { + MEM_free(attachments); + } + if (pref_vals != NULL) { + MEM_free(pref_vals); + } + //if (tc_root_file != NULL) { + // MEM_free(tc_root_file); + //} + printf("=========================·ERP End===================\n"); + return ifail; +} + + + + + +int RB_SendGX_New(EPM_action_message_t msg) +{ + printf("=========================·ERP Start===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + //+++ + char parameters[20000] = "";//д뵽ļֵ + strcat(parameters, "{\"data\":["); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + map> classMap; + for (int i = 0; i < attachments_num; i++) + { + tag_t bzgx = attachments[i]; + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(bzgx, &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + printf(">> classId: %s\n", classId); + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + if (strcmp("", parentClassName) == 0) { + DOFREE(parentClass); + DOFREE(parentClassId); + DOFREE(parentClassName); + DOFREE(classId); + continue; + } + } + DOFREE(parentClass); + DOFREE(parentClassId); + DOFREE(parentClassName); + char* type = NULL; + ITKCALL(AOM_ask_value_string(bzgx, "object_type", &type)); + if (strcmp("MEOPRevision", type) != 0) { + if (type != NULL) { + DOFREE(type); + } + continue; + } + if (strstr(parameters, "[{") != NULL) { + strcat(parameters, ","); + } + strcat(parameters, "{"); + char* bzgxh = NULL;//rb3_bzgxh + char* object_name = NULL;//object_name + char* bzgs = NULL;//rb3_bzgs + char* cplb = NULL;//Ʒ + char* cplb_disValue = NULL;//Ʒʾֵ + //ITKCALL(AOM_ask_value_string(bzgx, "rb3_bzgxh", &bzgxh)); + + ITKCALL(AOM_ask_value_string(bzgx, "object_name", &object_name)); + ITKCALL(AOM_ask_value_string(bzgx, "rb3_bzgs", &bzgs)); + + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + + if (attrMap.find("Ʒ") != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, "Ʒ", &cplb); + if (cplb != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(cplb, id, &cplb_disValue); + } + } + std::string str = classId; + if (str.length() >= 4) { + str.erase(0, 4); // ȥǰ4ַ + } + //removeFirstFourChars(classId); + strcat(parameters, "\"standardProcessNumber\":\""); + strcat(parameters, str.c_str()); + strcat(parameters, "\","); + strcat(parameters, "\"processName\":\""); + if (cplb_disValue != NULL) { + strcat(parameters, cplb_disValue); + strcat(parameters, "-"); + } + strcat(parameters, object_name); + strcat(parameters, "\","); + strcat(parameters, "\"standardWorkingHours\":\""); + strcat(parameters, bzgs); + strcat(parameters, "\","); + strcat(parameters, "\"productCategory\":\""); + if (cplb_disValue != NULL) { + strcat(parameters, cplb_disValue); + } + strcat(parameters, "\""); + strcat(parameters, "}"); + if (bzgxh != NULL) { + DOFREE(bzgxh); + } + if (object_name != NULL) { + DOFREE(object_name); + } + if (bzgs != NULL) { + DOFREE(bzgs); + } + if (cplb != NULL) { + DOFREE(cplb); + } + if (cplb_disValue != NULL) { + DOFREE(cplb_disValue); + } + if (classId != NULL) { + DOFREE(classId); + } + } + } + strcat(parameters, "],\"control\":{\"keydata\":null,\"ifid\": null,\"ifno\":\"TC_to_MDM_BZGX\",\"suser\": null,\"sysid\": null}}"); + printf("parameters: %s\n", parameters); + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + printf("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + //strcat(cmd, jar_file); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd,"@GX"); + ////strcat(cmd,handler_name); + //printf("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + strResult = strResult.substr(0, iSize - 1); + cout << strResult << endl; + if (strstr(strResult.c_str(), "\"code\":200") == NULL) + { + printf("·ʧ\n"); + + } + } + printf("ifail: %d\n", ifail); + if (attachments != NULL) { + MEM_free(attachments); + } + //if (tc_root_file != NULL) { + // MEM_free(tc_root_file); + //} + printf("=========================·ERP End===================\n"); + return ifail; +} diff --git a/CONNOR_ITK/RB_SendErpItem_New_Rule.cxx b/CONNOR_ITK/RB_SendErpItem_New_Rule.cxx new file mode 100644 index 0000000..25f6b9e --- /dev/null +++ b/CONNOR_ITK/RB_SendErpItem_New_Rule.cxx @@ -0,0 +1,1549 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" + +void removeSubstring(char* str, const char* toRemove) { + char* pos = strstr(str, toRemove); + if (pos != NULL) { + // Ӵ֮ǰƸ + memmove(pos, pos + strlen(toRemove), strlen(pos + strlen(toRemove)) + 1); + } +} +int RB_SendErpItem_New_Rule(EPM_rule_message_t msg) +{ + + char* log_file = NULL; + printf("־ļ\n"); + //char* TO_SRM = (char*)malloc(sizeof("TO_SRM")); + char tc_log_file_name[200] = ""; + strcpy(tc_log_file_name, "RB_SendErpItem_New_Rule"); + CreateLogFile(tc_log_file_name, &log_file); + + WriteLog("=========================·ERP Start rule===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = EPM_go; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + + char* job_name = NULL; + ITKCALL(AOM_ask_value_string(rootTask, "job_name", &job_name)); + WriteLog("ƣ%s\n", job_name); + int email_count = 0; + char** email_values; + ITKCALL(PREF_ask_char_values("RB_SEND_ERP_EMAIL", &email_count, &email_values)); + + vector mail_addrs; + + if (email_count > 0) { + + int valueCount = 0; + char** valueChar = new char* [128]; + //ַָ + split(email_values[0], ";", valueChar, &valueCount); + for (int i = 0; i < valueCount; i++) { + mail_addrs.push_back(valueChar[i]); + } + } + + + int user_cnt = mail_addrs.size(); + WriteLog("user_cnt===%d\n", user_cnt); + + + int pref_cnt = 0; + char** pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_ItemSendErp_Type_Attr", &pref_cnt, &pref_vals); + map> itemTypeMap; + map typePropertyType; + for (int i = 0; i < pref_cnt; i++) + { + if (strstr(pref_vals[i], ":") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(pref_vals[i], ":", valueChar, &valueCount); + if (strstr(valueChar[1], "|") != NULL) + { + int attrCount = 0; + char** attrChar = new char* [128]; + //ַָ + split(valueChar[1], "|", attrChar, &attrCount); + for (int j = 0; j < attrCount; j++) + { + if (strstr(attrChar[j], "=") != NULL) + { + int count = 0; + char** attrs = new char* [64]; + //ַָ + split(attrChar[j], "=", attrs, &count); + typePropertyType[attrs[0]] = attrs[1]; + DOFREE(attrs); + } + } + DOFREE(attrChar); + } + itemTypeMap[valueChar[0]] = typePropertyType; + typePropertyType.clear(); + DOFREE(valueChar); + + } + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int smzq_pref_cnt = 0; + char** smzq_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB3_WL_SMZQ", &smzq_pref_cnt, &smzq_pref_vals); + map smzqMap; + for (int i = 0; i < smzq_pref_cnt; i++) + { + if (strstr(smzq_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(smzq_pref_vals[i], "=", valueChar, &valueCount); + smzqMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + WriteLog("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + CloseLog(); + return 1; + } + + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + //+++ + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "["); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //"tc11","infodba","//172.16.50.40/tc11" "TC12","infodba","172.16.68.13/tc1" + + map> classMap; + for (int i = 0; i < attachments_num; i++) + { + int status = ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + WriteLog("status%d\n", status); + char* itemType = NULL; + + AOM_ask_value_string(attachments[i], "object_type", &itemType); + WriteLog("itemType%s\n", itemType); + + + //˵ǰ汾Ķ + if ((strstr(itemType, "Revision") == NULL) || (strstr(itemType, "Master") != NULL) + || (strstr(itemType, "master") != NULL) || (strstr(itemType, "BOM") != NULL) || (strstr(itemType, "bom") != NULL) || (strstr(itemType, "Bom") != NULL)) + { + DOFREE(itemType); + continue; + } + char* itemId1 = NULL; + AOM_ask_value_string(attachments[i], "item_id", &itemId1); + WriteLog("itemId1%s\n", itemId1); + if (itemTypeMap.find(itemType) != itemTypeMap.end()) { + map propMap = itemTypeMap[itemType]; + if (strstr(parameters, "[{") != NULL) { + strcat(parameters, ","); + } + strcat(parameters, "{"); + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(attachments[i], &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + WriteLog(">> classId: %s\n", classId); + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + } + + char* classCode = NULL; + char* cgCode = NULL; + char* className = NULL; + char* organization = NULL; + char* punit = NULL; + char factoryCode[2048] = "\0"; + //д,ʵ(ͬ) + if (status) + { + WriteLog("ʾ:мݱʧ\n"); + } + else { + char* field1 = NULL; + char* field2 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + WriteLog("ʾ:мݱʳɹ\n"); + //Ϸ⴦,ͨݿƥ + char sql[256] = "\0"; + if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 + || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_YCLRevision", itemType) == 0) { + if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field1); + DOFREE(value); + } + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field2)); + } + else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) + { + + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7') || startsWith(classId, '1', '3') || startsWith(classId, '1', '4')) { + + char* new_classId = NULL; + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) + { + new_classId = getFirstStr(classId, 2); + } + else + { + new_classId = getFirstStr(classId, 4); + } + tag_t classTag = NULLTAG; + char* id = NULL; + if (new_classId != NULL) { + ITKCALL(ICS_find_class(new_classId, &classTag)); + if (classTag != NULLTAG) + { + ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); + } + } + if (id != NULL) { + DOFREE(id); + } + if (classTag != NULL) { + DOFREE(classTag); + } + if (new_classId != NULL) { + DOFREE(new_classId); + } + } + else { + strcat(parameters, "}"); + continue; + + } + + + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "״", &value); + if (value != NULL) { + int id = attrMap["״"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + if (field1 != NULL) { + if (field1 != NULL && field2 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s' and PFIELD02= '%s'", itemType, field1, field2); + } + else { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + } + } + } + else { + if (strcmp("RB3_ZCRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_zclx", &field1)); + } + else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 + || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 + || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 + || strcmp("RB3_GZBJRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + } + else if (strcmp("RB3_SLRevision", itemType) == 0 + || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); + } + else if (strcmp("RB3_XZCPRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_cplx2", &field1)); + } + else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field1); + DOFREE(value); + } + } + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + } + } + WriteLog("sql==- %s \n", sql); + if (strcmp("", sql) != 0) { + WriteLog("ʾ:sql==%s\n", sql); + if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + if (field1 != NULL) { + char sql2[256] = "\0"; + sprintf(sql2, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + if (QuerySQLNoInputParam(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql2); + } + } + } + WriteLog("outputValueCount=%d\n", outputValueCount); + WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + if (outputValueCount > 0) { + classCode = outputValue[0][0]; + className = outputValue[0][1]; + organization = outputValue[0][2]; + punit = outputValue[0][3]; + WriteLog("Ϸ====%s\n", classCode); + WriteLog("====%s\n", className); + WriteLog("֯====%s\n", organization); + WriteLog("λ====%s\n", punit); + } + else { + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("ϷѯPLM_ERP_CLASS_TABLE"); + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-BOM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + DisConnServer(); + CloseLog(); + return EPM_go; + } + } + else { + + continue; + + } + + + // + //֯⴦,ͨݿƥ + char** factorys = NULL; + int factoryCount = 0; + if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_xzscgc", &factoryCount, &factorys)); + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0W + || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc", &factoryCount, &factorys)); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_sygc1", &factoryCount, &factorys)); + } + else { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc1", &factoryCount, &factorys)); + } + WriteLog("factoryCount=%d\n", factoryCount); + for (int j = 0; j < factoryCount; j++) + { + char*** factoryValue = NULL; + int factoryColumn = 0, factoryValueCount = 0; + char factorySql[128] = "\0"; + WriteLog("factorys[j]==%s\n", factorys[j]); + if (factorys[j] == NULL || strcmp(factorys[j], "") == 0 || strcmp(factorys[j], "0") == 0) { + sprintf(factorySql, "select PFACTORYCODE from PLM_ERP_FACTORY_TABLE where PFACTORY= 'globa100'"); + + } + else { + sprintf(factorySql, "select PFACTORYCODE from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", factorys[j]); + + } + WriteLog("ʾ:factorySql==%s\n", factorySql); + if (QuerySQLNoInputParam(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + WriteLog("factoryValueCount=%d\n", factoryValueCount); + WriteLog("factoryColumn=%d\n", factoryColumn); + //free(sql); + if (factoryValueCount > 0) { + + if (strcmp("", factoryCode) != 0) { + strcat(factoryCode, ","); + } + + strcat(factoryCode, factoryValue[0][0]); + WriteLog("֯====%s\n", factoryCode); + + } + else { + + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("֯ѯ,PLM_ERP_FACTORY_TABLE"); + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-BOM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + DisConnServer(); + CloseLog(); + return EPM_go; + } + WriteLog("1\n"); + if (factoryValue != NULL) { + WriteLog("2\n"); + DOFREE(factoryValue); + } + } + WriteLog("3\n"); + + + //ɹ⴦,ͨݿƥ + // + + char* limit_value = NULL; + char* object_name = NULL; + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &object_name)); + WriteLog("4\n"); + char* cgField1 = NULL; + char* cgField2 = NULL; + char* cgField3 = NULL; + char cgSql[256] = "\0"; + char cgSql2[256] = "\0"; + if (strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + //ȡobject_name롾ֵֶ2ƥ䣬ȡӦɹ롿д + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, object_name); + } + else if (strcmp("RB3_GQRevision", itemType) == 0) { + /* + ȡֶΡ𡿵ֵ롾ֵֶ2ƥ䣬 + ٻȡֶ3ֵֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + ֵȡ롾ֵֶ3бȶԣȡֵСڵһֵƥ䡾ɹ롿ĵһֵдݣ + ȡֵڵڵһֵСڵڶֵƥ䡾ɹ롿ĵڶֵдݣ + ȡֵڵڵڶֵƥ䡾ɹ롿ĵֵдݣ + */ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE03 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0) { + //ȸݻȡġERPϷࡿƥ䡾ֵֶ1ٸݡֶ2ݻȡǰλorǰλ + //ȡֵ롾ֵֶ2ƥ䣬ӶȡӦɹ롿дݣ + //IN41 IN38 ȡǰ4λ + char* newClassId = NULL; + if (strcmp("IN41", classCode) == 0 || strcmp("IN38", classCode) == 0) { + newClassId = getFirstStr(classId, 4); + } + else { + newClassId = getFirstStr(classId, 6); + } + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE01= '%s' and PFIELDVALUE02= '%s'", + itemType, classCode, newClassId); + } + else if (strcmp("RB3_GZRevision", itemType) == 0) { + /* + ȡӦֶΡֵ͡롾ֵֶ2ƥ䣬ٻȡֶ3ֵ + ֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + ֵȡ롾ֵֶ3бȶ + */ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + AOM_UIF_ask_value(attachments[i], "rb3_gzzj", &cgField3); + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE03 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else if (strcmp("RB3_LBJRevision", itemType) == 0) { + /* + ΪIN04IN03ȡϷ൹ڶ롾ֵֶ2ƥ䣬ٻȡֶ3ֵֶ3Ϊֱƥ䵽Ӧɹ롿дݣֵȡobject_name롾ֵֶ3ƥ䣻ٻȡֶ4ֵֶ4Ϊֱƥ䵽Ӧɹ롿дݣֶ4ֵֶ4ֵȡӦԵֵ롾ֵֶ4ƥȡɹ࣬ȶ߼ֵƥ߼˵ + ΪIN08ֱӻȡֶΡṹԡ롾ֵֶ3ƥ䣬ȡӦɹ롿дݣ + ΪIN09IN24ȡobject_name롾ֵֶ2ƥ䣬ȡӦɹ롿дݣ + */ + + if (classCode == NULL) { + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("ERPȡ,Ϸ!"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-ITEM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + CloseLog(); + return EPM_go; + } + + + if (strcmp("IN04", classCode) == 0 || strcmp("IN03", classCode) == 0) { + WriteLog("5\n"); + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + if (strstr(object_name, "Ȧ") != NULL || strcmp("Ȧ", object_name) == 0) { + //γߴ_⾶(mm) + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "γߴ_⾶(mm)", &value); + if (value != NULL) { + int id = attrMap["γߴ_⾶(mm)"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + } + else { + // γߴ_ھ(mm) + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "γߴ_ھ(mm)", &value); + if (value != NULL) { + int id = attrMap["γߴ_ھ(mm)"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + } + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s' and PFIELDVALUE01= '%s'", + itemType, parentClassName, object_name, classCode); + sprintf(cgSql2, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE01= '%s'", + itemType, parentClassName, classCode); + } + } + else if (strcmp("IN08", classCode) == 0) { + WriteLog("6\n"); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "ּ", &value); + if (value != NULL) { + WriteLog("value=====%s\n", value); + int id = attrMap["ּ"]; + WriteLog("id=====================%d\n", id); + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "ṹ", &value); + if (value != NULL) { + WriteLog("value=====%s\n", value); + int id = attrMap["ṹ"]; + WriteLog("id=====================%d\n", id); + getClassValue(value, id, &cgField2); + DOFREE(value); + } + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s'", + itemType, cgField1, cgField2); + } + else if (strcmp("IN09", classCode) == 0 || strcmp("IN24", classCode) == 0) { + WriteLog("7\n"); + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, object_name); + } + } + else if (strcmp("RB3_SLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0) { + //ֱӻȡӦɹ롿д + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s'", + itemType); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0) { + //ֱӻȡֶΡ״롾ֵֶ2ƥ䣬ٻȡֶ3ֵ + //ֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + //ֶ3ֵΪϹȡֶΡϹֵ롾ֵֶ3бȶԣ + // ȶ߼ֵƥ߼˵ + //ֶ3ֵΪ;ȡֶΡ;ֵ롾ֵֶ3ƥ䣬 + //ٻȡֶ4ֵֶ4Ϊֱƥ䵽Ӧɹ롿дݣ + //ֶ4ֵֶ4ֵȡӦԵֵ롾ֵֶ4ƥȡɹ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "״", &value); + if (value != NULL) { + int id = attrMap["״"]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, ";", &value); + if (value != NULL) { + int id = attrMap[";"]; + getClassValue(value, id, &cgField2); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "Ϲ", &value); + if (value != NULL) { + int id = attrMap["Ϲ"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + if (strcmp("IN01", classCode) == 0 || strcmp("IN02", classCode) == 0 || strcmp("IN53", classCode) == 0) { + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + //20250721 1ƥɹʱƥBIPϷࣻ + else if (strcmp("IN03", classCode) == 0 || strcmp("IN04", classCode) == 0) { + + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s' and PFIELDVALUE01= '%s'", + itemType, cgField1, cgField2, classCode); + } + else { + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s' and PFIELDVALUE01= '%s'", + itemType, cgField1, cgField2, classCode); + } + } + + int cgOutputColumn = 0, cgOutputValueCount = 0; + + char*** cgOutputValue = NULL; + + if (strcmp("", cgSql) != 0) { + WriteLog("ʾ:cgSql==%s\n", cgSql); + if (QuerySQLNoInputParam(cgSql, &cgOutputColumn, &cgOutputValueCount, &cgOutputValue) == -1 || cgOutputValueCount == 0) + { + if (cgOutputValue != NULL) { + for (int i1 = 0; i1 < cgOutputValueCount; i1++) { + for (int i2 = 0; i2 < cgOutputColumn; i2++) { + DOFREE(cgOutputValue[i1][i2]); + } + DOFREE(cgOutputValue[i1]); + } + DOFREE(cgOutputValue); + } + WriteLog("I2 => C=%d,R=%d\n", cgOutputColumn, cgOutputValueCount); + cgOutputColumn = 0; + cgOutputValueCount = 0; + cgOutputValue = NULL; + WriteLog("ʾ:ɹѯ ʧ, %s \n", cgSql); + if (QuerySQLNoInputParam(cgSql2, &cgOutputColumn, &cgOutputValueCount, &cgOutputValue) == -1) + { + WriteLog("ʾ:ɹѯ ʧ, %s \n", cgSql2); + } + } + WriteLog("cgOutputValueCount=%d\n", cgOutputValueCount); + WriteLog("cgOutputColumn=%d\n", cgOutputColumn); + + /*if (cgOutputValueCount <= 0) { + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("ɹѯʧ,PLM_ERP_CG_TABLE"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + return EPM_nogo; + }*/ + + //free(sql); + if (cgField3 != NULL && (strcmp("IN01", classCode) == 0 || strcmp("IN03", classCode) == 0 || strcmp("IN04", classCode) == 0 || strcmp("IN07", classCode) == 0 || strcmp("IN52", classCode) == 0)) { + WriteLog("111\n"); + WriteLog("cgField3======%s\n", cgField3); + char result[200]; // ȷresult㹻Դ洢 + // ڶַλ + size_t second_char_pos = 2; + if (strstr(cgField3, "") != NULL) + { + // ȡڶַ֮ + strcpy(result, cgField3 + second_char_pos); + WriteLog("1\n"); + } + if (strstr(cgField3, "") != NULL) + { + // ȡڶַ֮ + strcpy(result, cgField3 + second_char_pos); + WriteLog("2\n"); + } + WriteLog("cgField3====%s\n", result); + double result_num = atof(result); // תΪ + if (cgOutputValueCount > 0) { + cgCode = cgOutputValue[0][0]; + limit_value = cgOutputValue[0][1]; + WriteLog("ɹ====%s\n", cgCode); + WriteLog("ֵ====%s\n", limit_value); + if (limit_value != NULL + && strcmp(limit_value, "") != 0 + && strcmp(limit_value, " ") != 0) { + if (strstr(limit_value, "-") != NULL) + { + //-в֡ + int numCount = 0; + char** numChar = new char* [64]; + int valCount = 0; + char** valChar = new char* [64]; + //ַָ + split(limit_value, "-", numChar, &numCount); + split(cgCode, ",", valChar, &valCount); + for (int ii = 0; ii < numCount; ii++) + { + double int_value1 = atof(numChar[ii]); + if (result_num < int_value1) { + cgCode = valChar[ii]; + break; + } + else { + if (ii != numCount - 1) { + double int_value2 = atof(numChar[ii + 1]); + if (result_num < int_value2) { + cgCode = valChar[ii + 1]; + break; + } + } + else { + cgCode = valChar[numCount - 1]; + break; + } + } + } + DOFREE(numChar); + } + } + WriteLog("ɹ====%s\n", cgCode); + } + } + else { + WriteLog("222\n"); + if (cgOutputValueCount > 0) { + cgCode = cgOutputValue[0][0]; + } + /*if (true) { + return 0; + }*/ + WriteLog("333\n"); + } + if (object_name != NULL) { + DOFREE(object_name); + } + if (limit_value != NULL) { + DOFREE(limit_value); + } + } + + + if (factorys != NULL) { + DOFREE(factorys); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + if (cgField1 != NULL) { + DOFREE(cgField1); + } + if (cgField2 != NULL) { + DOFREE(cgField2); + } + if (cgField3 != NULL) { + DOFREE(cgField3); + } + } + if (factoryCode != NULL) { + strcat(parameters, "\"orgCode\":\""); + int fattrCount = 0; + char** fattrChar = new char* [128]; + WriteLog("factoryCode=============%s\n", factoryCode); + split(factoryCode, ",", fattrChar, &fattrCount); + + string factoryCodeStr = ""; + for (int g = 0; g < fattrCount; g++) { + + if (!strstr(factoryCodeStr.c_str(), fattrChar[g])) { + factoryCodeStr.append(fattrChar[g]); + factoryCodeStr.append(","); + } + } + WriteLog("factoryCodeStr.c_str()=============%s\n", factoryCodeStr.c_str()); + strcat(parameters, factoryCodeStr.c_str()); + if (organization != NULL && strcmp(organization, "") != 0) { + strcat(parameters, ","); + strcat(parameters, organization); + } + strcat(parameters, "\","); + } + strcat(parameters, "\"manageClassCode\":\""); + if (classCode != NULL) { + strcat(parameters, classCode); + } + strcat(parameters, "\","); + strcat(parameters, "\"purchaseClassCode\":\""); + if (cgCode != NULL) { + strcat(parameters, cgCode); + } + else { + strcat(parameters, ""); + } + strcat(parameters, "\","); + // ʹõmap + int index = 0; + for (std::map::iterator it = propMap.begin(); it != propMap.end(); ++it) { + string key = it->first; + string attr = it->second; + WriteLog("key: %s \n", key.c_str()); + WriteLog("attr: %s \n", attr.c_str()); + if (strcmp("orgCode", key.c_str()) == 0) { + index++; + continue; + } + if (strstr(attr.c_str(), ".") != NULL) + { + int attrCount = 0; + char** attrChar = new char* [128]; + char* attrName = new char[2048];//㹻 + strcpy(attrName, attr.c_str()); + WriteLog("attrName: %s \n", attrName); + //ַָ + split(attrName, ".", attrChar, &attrCount); + char* value = NULL; + if (strcmp("rev", attrChar[0]) == 0) { + //λ⴦ + if (strcmp("uom_tag", attrChar[1]) == 0) + { + //tag_t item = NULLTAG; + //ITKCALL(ITEM_ask_item_of_rev(attachments[i], &item)); + //tag_t unitTag = NULLTAG; + //ITKCALL(AOM_ask_value_tag(item, attrChar[1], &unitTag)); + //if (unitTag != NULL) { + // ITKCALL(AOM_UIF_ask_value(unitTag, "object_string", &value)); + // WriteLog("uom_tag: %s \n", value); + // //λ + // // ضϷ൥λ㣺λLתWL֬ļλGM() תKGǧˣ;ֲģֹܼλGM()תT֣ + // if (className != NULL) { + // if (strcmp("", className) == 0 && strcmp("L()", value) == 0) + // { + // value = "WL()"; + // } + // else if (strcmp("֬", className) == 0 && strcmp("GM()", value) == 0) + // { + // value = "KG(ǧ)"; + // }if ((strcmp("ֲ", className) == 0 || strcmp("ֹ", className) == 0) && strcmp("GM()", value) == 0) + // { + // value = "T()"; + // } + // } + // strcat(parameters, "\""); + // strcat(parameters, key.c_str()); + // strcat(parameters, "\":\""); + // if (unitMap.find(value) != unitMap.end()) { + // strcat(parameters, unitMap[value].c_str()); + // } + // else { + // strcat(parameters, value); + // } + // strcat(parameters, "\""); + //} + //else { + // strcat(parameters, "\""); + // strcat(parameters, key.c_str()); + // strcat(parameters, "\":\""); + // if (punit != NULL) { + // strcat(parameters, punit); + // } + // strcat(parameters, "\""); + + //} + //if (item != NULL) { + // DOFREE(item); + //} + //if (unitTag != NULL) { + // DOFREE(unitTag); + //} + // + //20250721޸ 5λֶԭضתΪȫBIPȡϷձеĵλ + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (punit != NULL) { + strcat(parameters, punit); + } + strcat(parameters, "\""); + } + //⴦ + else if (strcmp("netWeight", key.c_str()) == 0) + { + strcat(parameters, "\"netWeightUnitCode\":\"KG\","); + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + WriteLog("value=============================%s\n", value); + if (value != NULL && strcmp("", value) != 0 && strcmp(value, "/") != 0) { + double dValue = std::stod(value); + dValue = dValue * 10000; + long lValue = static_cast(dValue); // תΪlong + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":"); + char netWeight[64] = "\0"; + sprintf(netWeight, "%d", lValue); + strcat(parameters, netWeight); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":0"); + } + } + //⴦ + else if (strcmp("material_status", key.c_str()) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (smzqMap.find(value) != smzqMap.end()) { + strcat(parameters, smzqMap[value].c_str()); + } + else { + strcat(parameters, value); + } + strcat(parameters, "\""); + } + //rb3_th ⴦ + else if (strcmp("rb3_th", attrChar[1]) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + WriteLog("rb3_th====%s\n", value); + + if (strstr(value,"XX-") || strstr(value, "SF-")) { + removeSubstring(value, "XX-"); + removeSubstring(value, "SF-"); + } + WriteLog("rb3_th===========%s\n", value); + + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, value); + strcat(parameters, "\""); + } + else { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, value); + strcat(parameters, "\""); + } + } + else { + if (ico_tag != NULLTAG) { + //if (strstr(attrChar[1], "&") != NULL) + //{ + // int attrNum = 0; + // char** allAttrs = new char* [128]; + // //ַָ + // split(attrChar[1], "&", allAttrs, &attrNum); + // char values[256] = "";//ƴ + // for (int i = 0; i < attrNum; i++) + // { + // if (attrMap.find(allAttrs[i]) != attrMap.end()) + // { + // ICS_ask_attribute_value(ico_tag, allAttrs[i], &value); + // if (value != NULL) { + // int id = attrMap[allAttrs[i]]; + // char* disValue; + // getClassValue(value, id, &disValue); + // strcat(values, disValue); + // DOFREE(disValue); + // } + // else { + // strcat(values, ""); + // } + // } + // else { + // strcat(values, ""); + // } + // } + // strcat(parameters, "\""); + // strcat(parameters, key.c_str()); + // strcat(parameters, "\":\""); + // strcat(parameters, values); + // strcat(parameters, "\""); + // DOFREE(allAttrs); + //} + + //20250721 ȥ"" ƴӵ߼ + + if (strstr(attrChar[1], "&") != NULL) + { + int attrNum = 0; + char** allAttrs = new char* [128]; + //ַָ + split(attrChar[1], "&", allAttrs, &attrNum); + WriteLog("---attrChar===========%s\n", attrChar[1]); + char values[256] = "";//ƴ + for (int i = 0; i < attrNum; i++) + { + if (attrMap.find(allAttrs[i]) != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, allAttrs[i], &value); + + WriteLog("---value===========%s\n", value); + WriteLog("---allAttrs[i]===========%s\n", allAttrs[i]); + + if (strcmp(allAttrs[i], "񶯼ٶ") == 0 || strcmp(allAttrs[i], "񶯵ȼ") == 0 || strcmp(allAttrs[i], "ٶ") == 0) { + if (value != NULL) { + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("---disValue1===========%s\n", disValue); + if (strcmp(disValue, "") == 0) { + strcat(values, ""); + } + else { + if (strstr(disValue, ":")) { + int mhNum = 0; + char** mhAttrs = new char* [128]; + //ַָ + split(disValue, ":", mhAttrs, &mhNum); + WriteLog("---mhAttrs===========%s\n", mhAttrs[0]); + strcat(values, mhAttrs[0]); + } + else { + + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("---disValue22===========%s\n", disValue); + strcat(values, disValue); + } + + } + + + DOFREE(disValue); + } + } + else { + if (value != NULL) { + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("---disValue===========%s\n", disValue); + strcat(values, disValue); + DOFREE(disValue); + } + + } + + } + else { + strcat(values, ""); + } + } + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, values); + strcat(parameters, "\""); + DOFREE(allAttrs); + } + else { + //ּܰ⴦ + if (strcmp("CU0261", key.c_str()) == 0) + { + if (attrMap.find("ּܰ(mm)") != attrMap.end()) + { + attrChar[1] = "ּܰ(mm)"; + } + else if (attrMap.find("ѹּܰ(mm)") != attrMap.end()) + { + attrChar[1] = "ѹּܰ(mm)"; + } + else if (attrMap.find("ּܰ()") != attrMap.end()) + { + attrChar[1] = "ּܰ()"; + } + } + //ܷɫ⴦ + else if (strcmp("CU0262", key.c_str()) == 0) + { + if (attrMap.find("ܷɫ") != attrMap.end()) + { + //WriteLog("1111\n"); + attrChar[1] = "ܷɫ"; + } + else if (attrMap.find("ܷɫ(ֶ)") != attrMap.end()) + { + attrChar[1] = "ܷɫ(ֶ)"; + } + else if (attrMap.find("(ܷɫ)") != attrMap.end()) + { + attrChar[1] = "(ܷɫ)"; + } + } + //ܷ⴦ + else if (strcmp("CU0263", key.c_str()) == 0) + { + if (attrMap.find("ܷ") != attrMap.end()) + { + //WriteLog("2222\n"); + attrChar[1] = "ܷ"; + } + else if (attrMap.find("ܷ(ֶ)") != attrMap.end()) + { + attrChar[1] = "ܷ(ֶ)"; + } + else if (attrMap.find("(ܷ)") != attrMap.end()) + { + attrChar[1] = "(ܷ)"; + } + } + //WriteLog("attrChar[1] = %s \n", attrChar[1]); + if (attrMap.find(attrChar[1]) != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, attrChar[1], &value); + if (value != NULL && strcmp(value, "") != 0 && strcmp(value, " ") != 0) { + int id = attrMap[attrChar[1]]; + char* disValue; + getClassValue(value, id, &disValue); + /* WriteLog("id = %d \n", id); + WriteLog("disValue = %s \n", disValue);*/ + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, disValue); + strcat(parameters, "\""); + DOFREE(disValue); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + WriteLog("value: %s \n", value); + DOFREE(value); + DOFREE(attrChar); + DOFREE(attrName); + } + else { + if (strcmp("CU0266", key.c_str()) == 0 && strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + WriteLog("㲿⴦\n"); + char* value = NULL; + if (attrMap.find("") != attrMap.end()) + { + + ICS_ask_attribute_value(ico_tag, "", &value); + WriteLog(" : %s \n", value); + if (value != NULL && strcmp(value,"") != 0) { + int id = attrMap[""]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("disValue : %s \n", disValue); + if (disValue != NULL && strcmp("C:", disValue) == 0) { + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, parentClassName); + strcat(parameters, "\""); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(parentClass); + DOFREE(parentClassId); + DOFREE(parentClassName); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(disValue); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + else + { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(value); + }//⴦ + else if (strcmp("netWeight", key.c_str()) == 0) + { + strcat(parameters, "\"netWeightUnitCode\":\"KG\","); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":0"); + } + else + { + WriteLog("key: %s ĬΪֵ\n", key.c_str()); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + if (index < propMap.size() - 1) + { + strcat(parameters, ","); + } + index++; + } + if (classId != NULL) { + DOFREE(classId); + } + if (ico_tag != NULL) { + DOFREE(ico_tag); + } + if (classCode != NULL) { + DOFREE(classCode); + } + if (cgCode != NULL) { + DOFREE(cgCode); + } + if (className != NULL) { + DOFREE(className); + } + if (organization != NULL) { + DOFREE(organization); + } + if (punit != NULL) { + DOFREE(punit); + } + strcat(parameters, "}"); + attrMap.clear(); + } + DOFREE(itemType); + DisConnServer(); + } + + strcat(parameters, "]"); + //WriteLog("parameters: %s\n", parameters); + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + WriteLog("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@WL"); + //WriteLog("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + WriteLog("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + char errorMessage[100000] = "";//д뵽ļֵ + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + + strResult = strResult.substr(0, iSize - 1); + //WriteLog("·ʧ\n"); + //cout << strResult << endl; + + if (strstr(strResult.c_str(), "\"code\":200") != NULL) + { + WriteLog("·ɹ\n"); + + } + else { + + + strcat(errorMessage, strResult.c_str()); + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-ITEM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":ʧ->"); + strcat_s(cmd, errorMessage); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + + + ifail = EPM_go; + } + } + WriteLog("ifail: %d\n", ifail); + if (attachments != NULL) { + MEM_free(attachments); + } + if (pref_vals != NULL) { + MEM_free(pref_vals); + } + //if (tc_root_file != NULL) { + // MEM_free(tc_root_file); + //} + + + /*if (ifail == EPM_nogo) + { + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + + }*/ + + WriteLog("=========================·ERP rule End===================\n"); + CloseLog(); + return ifail; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_SendErpItem_New_Rule_Release.cxx b/CONNOR_ITK/RB_SendErpItem_New_Rule_Release.cxx new file mode 100644 index 0000000..e5100df --- /dev/null +++ b/CONNOR_ITK/RB_SendErpItem_New_Rule_Release.cxx @@ -0,0 +1,1527 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" + +void removeSubstringRelease(char* str, const char* toRemove) { + char* pos = strstr(str, toRemove); + if (pos != NULL) { + // Ӵ֮ǰƸ + memmove(pos, pos + strlen(toRemove), strlen(pos + strlen(toRemove)) + 1); + } +} + +int RB_SendErpItem_New_Rule_Release(EPM_rule_message_t msg) +{ + + char* log_file = NULL; + printf("־ļ\n"); + //char* TO_SRM = (char*)malloc(sizeof("TO_SRM")); + char tc_log_file_name[200] = ""; + strcpy(tc_log_file_name, "RB_SendErpItem_New_Rule_Release"); + CreateLogFile(tc_log_file_name, &log_file); + + + WriteLog("=========================·ERP Start rule release===================\n"); + //POM_AM__set_application_bypass(true); + int ifail = EPM_go; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + + + char* job_name = NULL; + ITKCALL(AOM_ask_value_string(rootTask, "job_name", &job_name)); + WriteLog("ƣ%s\n", job_name); + int email_count = 0; + char** email_values; + ITKCALL(PREF_ask_char_values("RB_SEND_ERP_EMAIL", &email_count, &email_values)); + + vector mail_addrs; + + if (email_count > 0) { + + int valueCount = 0; + char** valueChar = new char* [128]; + //ַָ + split(email_values[0], ";", valueChar, &valueCount); + for (int i = 0; i < valueCount; i++) { + mail_addrs.push_back(valueChar[i]); + } + } + + + int user_cnt = mail_addrs.size(); + WriteLog("user_cnt===%d\n", user_cnt); + + + + int pref_cnt = 0; + char** pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_ItemSendErp_Type_Attr", &pref_cnt, &pref_vals); + map> itemTypeMap; + map typePropertyType; + for (int i = 0; i < pref_cnt; i++) + { + if (strstr(pref_vals[i], ":") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(pref_vals[i], ":", valueChar, &valueCount); + if (strstr(valueChar[1], "|") != NULL) + { + int attrCount = 0; + char** attrChar = new char* [128]; + //ַָ + split(valueChar[1], "|", attrChar, &attrCount); + for (int j = 0; j < attrCount; j++) + { + if (strstr(attrChar[j], "=") != NULL) + { + int count = 0; + char** attrs = new char* [64]; + //ַָ + split(attrChar[j], "=", attrs, &count); + typePropertyType[attrs[0]] = attrs[1]; + DOFREE(attrs); + } + } + DOFREE(attrChar); + } + itemTypeMap[valueChar[0]] = typePropertyType; + typePropertyType.clear(); + DOFREE(valueChar); + + } + } + int unit_pref_cnt = 0; + char** unit_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB_SEND_UNIT_MATCHING", &unit_pref_cnt, &unit_pref_vals); + map unitMap; + for (int i = 0; i < unit_pref_cnt; i++) + { + if (strstr(unit_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(unit_pref_vals[i], "=", valueChar, &valueCount); + unitMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int smzq_pref_cnt = 0; + char** smzq_pref_vals = NULL; + //ȡѡֵ + PREF_ask_char_values("RB3_WL_SMZQ", &smzq_pref_cnt, &smzq_pref_vals); + map smzqMap; + for (int i = 0; i < smzq_pref_cnt; i++) + { + if (strstr(smzq_pref_vals[i], "=") != NULL) + { + //-в֡ + int valueCount = 0; + char** valueChar = new char* [64]; + //ַָ + split(smzq_pref_vals[i], "=", valueChar, &valueCount); + smzqMap[valueChar[0]] = valueChar[1]; + DOFREE(valueChar); + } + } + int c_sql_value_count = 0; + char** c_sql_values; + ITKCALL(PREF_ask_char_values("RB3_SQL_Connect2", &c_sql_value_count, &c_sql_values)); + if (c_sql_value_count != 3) + { + WriteLog("ѡ RB3_SQL_Connect2 ô %d ", c_sql_value_count); + CloseLog(); + return 1; + } + + char* tc_root_file = getenv("tc_root"); //C:\Siemens\Teamcenter11 + //+++ + char parameters[100000] = "";//д뵽ļֵ + strcat(parameters, "["); + //ȡǰʱ + time_t now = time(0); + tm* p = localtime(&now); + char date[128] = ""; + sprintf_s(date, "%04d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + //"tc11","infodba","//172.16.50.40/tc11" "TC12","infodba","172.16.68.13/tc1" + + map> classMap; + for (int i = 0; i < attachments_num; i++) + { + int status = ConnServer(c_sql_values[1], c_sql_values[2], c_sql_values[0]); + WriteLog("status%d\n", status); + char* itemType = NULL; + + AOM_ask_value_string(attachments[i], "object_type", &itemType); + WriteLog("itemType%s\n", itemType); + + + //˵ǰ汾Ķ + if ((strstr(itemType, "Revision") == NULL) || (strstr(itemType, "Master") != NULL) + || (strstr(itemType, "master") != NULL) || (strstr(itemType, "BOM") != NULL) || (strstr(itemType, "bom") != NULL) || (strstr(itemType, "Bom") != NULL)) + { + DOFREE(itemType); + continue; + } + char* itemId1 = NULL; + AOM_ask_value_string(attachments[i], "item_id", &itemId1); + WriteLog("itemId1%s\n", itemId1); + if (itemTypeMap.find(itemType) != itemTypeMap.end()) { + map propMap = itemTypeMap[itemType]; + if (strstr(parameters, "[{") != NULL) { + strcat(parameters, ","); + } + strcat(parameters, "{"); + tag_t ico_tag = NULLTAG; + char* classId = NULL; + map attrMap; + ICS_ask_classification_object(attachments[i], &ico_tag); + if (ico_tag != NULLTAG) { + ICS_ico_ask_class(ico_tag, &classId); + WriteLog(">> classId: %s\n", classId); + //ƶӦid map洢 + if (classMap.find(classId) == classMap.end()) { + int count = 0; + int* ids; + int* arraySize; + int* formats; + int* options; + char** names; + char** shortNames; + char** annotations; + char** unit; + char** minValues; + char** maxValues; + char** defaultValues; + char** descriptions; + ITKCALL(ICS_class_describe_attributes(classId, &count, &ids, &names, &shortNames, &annotations, &arraySize, + &formats, &unit, &minValues, &maxValues, &defaultValues, &descriptions, &options)); + for (int i = 0; i < count; i++) + { + attrMap.insert(pair(names[i], ids[i])); + } + classMap.insert(pair>(classId, attrMap)); + if (ids != NULL) { + DOFREE(ids); + } + if (arraySize != NULL) { + DOFREE(arraySize); + } + if (formats != NULL) { + DOFREE(formats); + } + if (options != NULL) { + DOFREE(options); + } + if (names != NULL) { + DOFREE(names); + } + if (shortNames != NULL) { + DOFREE(shortNames); + } + if (annotations != NULL) { + DOFREE(annotations); + } + if (unit != NULL) { + DOFREE(unit); + } + if (minValues != NULL) { + DOFREE(minValues); + } + if (maxValues != NULL) { + DOFREE(maxValues); + } + if (defaultValues != NULL) { + DOFREE(defaultValues); + } + if (descriptions != NULL) { + DOFREE(descriptions); + } + } + else { + attrMap = classMap[classId]; + } + } + + char* classCode = NULL; + char* cgCode = NULL; + char* className = NULL; + char* organization = NULL; + char* punit = NULL; + char factoryCode[2048] = "\0"; + //д,ʵ(ͬ) + if (status) + { + WriteLog("ʾ:мݱʧ\n"); + } + else { + char* field1 = NULL; + char* field2 = NULL; + int outputColumn = 0, outputValueCount = 0; + char*** outputValue = NULL; + WriteLog("ʾ:мݱʳɹ\n"); + //Ϸ⴦,ͨݿƥ + char sql[256] = "\0"; + if (strcmp("RB3_LBJRevision", itemType) == 0 || strcmp("RB3_GNZCRevision", itemType) == 0 + || strcmp("RB3_GNLBJRevision", itemType) == 0 || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_YCLRevision", itemType) == 0) { + if (strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field1); + DOFREE(value); + } + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field2)); + } + else if (strcmp("RB3_GNLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "Ʒ", &value); + if (value != NULL) { + int id = attrMap["Ʒ"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0 && ico_tag != NULLTAG) + { + + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7') || startsWith(classId, '1', '3') || startsWith(classId, '1', '4')) { + + char* new_classId = NULL; + if (startsWith(classId, '1', '2') || startsWith(classId, '1', '7')) + { + new_classId = getFirstStr(classId, 2); + } + else + { + new_classId = getFirstStr(classId, 4); + } + tag_t classTag = NULLTAG; + char* id = NULL; + if (new_classId != NULL) { + ITKCALL(ICS_find_class(new_classId, &classTag)); + if (classTag != NULLTAG) + { + ITKCALL(ICS_ask_id_name(classTag, &id, &field1)); + } + } + if (id != NULL) { + DOFREE(id); + } + if (classTag != NULL) { + DOFREE(classTag); + } + if (new_classId != NULL) { + DOFREE(new_classId); + } + } + else { + strcat(parameters, "}"); + continue; + + } + + + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 && ico_tag != NULLTAG) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "״", &value); + if (value != NULL) { + int id = attrMap["״"]; + getClassValue(value, id, &field2); + DOFREE(value); + } + } + if (field1 != NULL) { + if (field1 != NULL && field2 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s' and PFIELD02= '%s'", itemType, field1, field2); + } + else { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + } + } + } + else { + if (strcmp("RB3_ZCRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_zclx", &field1)); + } + else if (strcmp("RB3_BZJRevision", itemType) == 0 || strcmp("RB3_BZJBJRevision", itemType) == 0 + || strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_GQRevision", itemType) == 0 + || strcmp("RB3_GQBJRevision", itemType) == 0 || strcmp("RB3_GZRevision", itemType) == 0 + || strcmp("RB3_GZBJRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &field1)); + } + else if (strcmp("RB3_SLRevision", itemType) == 0 + || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_bjlx", &field1)); + } + else if (strcmp("RB3_XZCPRevision", itemType) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], "rb3_cplx2", &field1)); + } + else if (strcmp("RB3_XZLBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &field1); + DOFREE(value); + } + } + if (field1 != NULL) { + sprintf(sql, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + } + } + WriteLog("sql==- %s \n", sql); + if (strcmp("", sql) != 0) { + WriteLog("ʾ:sql==%s\n", sql); + if (QuerySQLNoInputParam(sql, &outputColumn, &outputValueCount, &outputValue) == -1 || outputValueCount == 0) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql); + if (field1 != NULL) { + char sql2[256] = "\0"; + sprintf(sql2, "select PCLASSCODE,PCLASSNAME,NEW_COLUMN,PUNIT from PLM_ERP_CLASS_TABLE where PTYPE= '%s' and PFIELD01= '%s'", itemType, field1); + if (QuerySQLNoInputParam(sql2, &outputColumn, &outputValueCount, &outputValue) == -1) + { + WriteLog("ʾ:Ϸѯ ʧ, %s \n", sql2); + } + } + } + WriteLog("outputValueCount=%d\n", outputValueCount); + WriteLog("outputColumn=%d\n", outputColumn); + //free(sql); + if (outputValueCount > 0) { + classCode = outputValue[0][0]; + className = outputValue[0][1]; + organization = outputValue[0][2]; + punit = outputValue[0][3]; + WriteLog("Ϸ====%s\n", classCode); + WriteLog("====%s\n", className); + WriteLog("֯====%s\n", organization); + WriteLog("λ====%s\n", punit); + } + else { + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("ϷѯPLM_ERP_CLASS_TABLE"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + DisConnServer(); + + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-ITEM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + + return EPM_nogo; + CloseLog(); + } + } + else { + + continue; + + } + + + // + //֯⴦,ͨݿƥ + char** factorys = NULL; + int factoryCount = 0; + if (strcmp("RB3_XZCPRevision", itemType) == 0 || strcmp("RB3_XZLBJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_xzscgc", &factoryCount, &factorys)); + } + else if (strcmp("RB3_GNZCRevision", itemType) == 0 || strcmp("RB3_GNLBJRevision", itemType) == 0 + || strcmp("RB3_GYZYRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc", &factoryCount, &factorys)); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0 || strcmp("RB3_WJTLRevision", itemType) == 0 || strcmp("RB3_SLRevision", itemType) == 0) { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_sygc1", &factoryCount, &factorys)); + } + else { + ITKCALL(AOM_UIF_ask_values(attachments[i], "rb3_scgc1", &factoryCount, &factorys)); + } + WriteLog("factoryCount=%d\n", factoryCount); + for (int j = 0; j < factoryCount; j++) + { + char*** factoryValue = NULL; + int factoryColumn = 0, factoryValueCount = 0; + char factorySql[128] = "\0"; + WriteLog("factorys[j]==%s\n", factorys[j]); + if (factorys[j] == NULL || strcmp(factorys[j],"") == 0 || strcmp(factorys[j], "0") == 0) { + sprintf(factorySql, "select PFACTORYCODE from PLM_ERP_FACTORY_TABLE where PFACTORY= 'globa100'"); + + } + else { + sprintf(factorySql, "select PFACTORYCODE from PLM_ERP_FACTORY_TABLE where PFACTORY= '%s'", factorys[j]); + + } + + WriteLog("ʾ:factorySql==%s\n", factorySql); + if (QuerySQLNoInputParam(factorySql, &factoryColumn, &factoryValueCount, &factoryValue) == -1) + { + WriteLog("ʾ:֯ѯ ʧ, %s \n", factorySql); + } + WriteLog("factoryValueCount=%d\n", factoryValueCount); + WriteLog("factoryColumn=%d\n", factoryColumn); + //free(sql); + if (factoryValueCount > 0) { + + if (strcmp("", factoryCode) != 0) { + strcat(factoryCode, ","); + } + + strcat(factoryCode, factoryValue[0][0]); + WriteLog("֯====%s\n", factoryCode); + } + else { + + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("֯ѯ,PLM_ERP_FACTORY_TABLE"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + DisConnServer(); + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-ITEM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + return EPM_nogo; + CloseLog(); + } + WriteLog("1\n"); + if (factoryValue != NULL) { + WriteLog("2\n"); + DOFREE(factoryValue); + } + } + WriteLog("3\n"); + + + //ɹ⴦,ͨݿƥ + // + + char* limit_value = NULL; + char* object_name = NULL; + ITKCALL(AOM_UIF_ask_value(attachments[i], "object_name", &object_name)); + WriteLog("4\n"); + char* cgField1 = NULL; + char* cgField2 = NULL; + char* cgField3 = NULL; + char cgSql[256] = "\0"; + char cgSql2[256] = "\0"; + if (strcmp("RB3_YZRevision", itemType) == 0 || strcmp("RB3_BZJRevision", itemType) == 0) { + //ȡobject_name롾ֵֶ2ƥ䣬ȡӦɹ롿д + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, object_name); + } + else if (strcmp("RB3_GQRevision", itemType) == 0) { + /* + ȡֶΡ𡿵ֵ롾ֵֶ2ƥ䣬 + ٻȡֶ3ֵֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + ֵȡ롾ֵֶ3бȶԣȡֵСڵһֵƥ䡾ɹ롿ĵһֵдݣ + ȡֵڵڵһֵСڵڶֵƥ䡾ɹ롿ĵڶֵдݣ + ȡֵڵڵڶֵƥ䡾ɹ롿ĵֵдݣ + */ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE03 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else if (strcmp("RB3_GYZYRevision", itemType) == 0) { + //ȸݻȡġERPϷࡿƥ䡾ֵֶ1ٸݡֶ2ݻȡǰλorǰλ + //ȡֵ롾ֵֶ2ƥ䣬ӶȡӦɹ롿дݣ + //IN41 IN38 ȡǰ4λ + char* newClassId = NULL; + if (strcmp("IN41", classCode) == 0 || strcmp("IN38", classCode) == 0) { + newClassId = getFirstStr(classId, 4); + } + else { + newClassId = getFirstStr(classId, 6); + } + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE01= '%s' and PFIELDVALUE02= '%s'", + itemType, classCode, newClassId); + } + else if (strcmp("RB3_GZRevision", itemType) == 0) { + /* + ȡӦֶΡֵ͡롾ֵֶ2ƥ䣬ٻȡֶ3ֵ + ֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + ֵȡ롾ֵֶ3бȶ + */ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "", &value); + if (value != NULL) { + int id = attrMap[""]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + AOM_UIF_ask_value(attachments[i], "rb3_gzzj", &cgField3); + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE03 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + else if (strcmp("RB3_LBJRevision", itemType) == 0) { + /* + ΪIN04IN03ȡϷ൹ڶ롾ֵֶ2ƥ䣬ٻȡֶ3ֵֶ3Ϊֱƥ䵽Ӧɹ롿дݣֵȡobject_name롾ֵֶ3ƥ䣻ٻȡֶ4ֵֶ4Ϊֱƥ䵽Ӧɹ롿дݣֶ4ֵֶ4ֵȡӦԵֵ롾ֵֶ4ƥȡɹ࣬ȶ߼ֵƥ߼˵ + ΪIN08ֱӻȡֶΡṹԡ롾ֵֶ3ƥ䣬ȡӦɹ롿дݣ + ΪIN09IN24ȡobject_name롾ֵֶ2ƥ䣬ȡӦɹ롿дݣ + */ + + if (classCode == NULL) { + + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("ERPȡ,Ϸ!"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if (mail_addr.size() > 0) { + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-ITEM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":֯ʧ->"); + strcat_s(cmd, errMsg.c_str()); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + return EPM_nogo; + CloseLog(); + } + + if (strcmp("IN04", classCode) == 0 || strcmp("IN03", classCode) == 0) { + WriteLog("5\n"); + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + if (strstr(object_name, "Ȧ") != NULL || strcmp("Ȧ", object_name) == 0) { + //γߴ_⾶(mm) + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "γߴ_⾶(mm)", &value); + if (value != NULL) { + int id = attrMap["γߴ_⾶(mm)"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + } + else { + // γߴ_ھ(mm) + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "γߴ_ھ(mm)", &value); + if (value != NULL) { + int id = attrMap["γߴ_ھ(mm)"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + } + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s' and PFIELDVALUE01= '%s'", + itemType, parentClassName, object_name, classCode); + sprintf(cgSql2, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE01= '%s'", + itemType, parentClassName, classCode); + } + } + else if (strcmp("IN08", classCode) == 0) { + WriteLog("6\n"); + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "ּ", &value); + if (value != NULL) { + WriteLog("value=====%s\n", value); + int id = attrMap["ּ"]; + WriteLog("id=====================%d\n", id); + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "ṹ", &value); + if (value != NULL) { + WriteLog("value=====%s\n", value); + int id = attrMap["ṹ"]; + WriteLog("id=====================%d\n", id); + getClassValue(value, id, &cgField2); + DOFREE(value); + } + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s'", + itemType, cgField1, cgField2); + } + else if (strcmp("IN09", classCode) == 0 || strcmp("IN24", classCode) == 0) { + WriteLog("7\n"); + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, object_name); + } + } + else if (strcmp("RB3_SLRevision", itemType) == 0 || strcmp("RB3_XJRevision", itemType) == 0) { + //ֱӻȡӦɹ롿д + sprintf(cgSql, + "select PCGCODE from PLM_ERP_CG_TABLE where PTYPE= '%s'", + itemType); + } + else if (strcmp("RB3_YCLRevision", itemType) == 0) { + //ֱӻȡֶΡ״롾ֵֶ2ƥ䣬ٻȡֶ3ֵ + //ֶ3Ϊֱƥ䵽Ӧɹ롿дݣ + //ֶ3ֵΪϹȡֶΡϹֵ롾ֵֶ3бȶԣ + // ȶ߼ֵƥ߼˵ + //ֶ3ֵΪ;ȡֶΡ;ֵ롾ֵֶ3ƥ䣬 + //ٻȡֶ4ֵֶ4Ϊֱƥ䵽Ӧɹ롿дݣ + //ֶ4ֵֶ4ֵȡӦԵֵ롾ֵֶ4ƥȡɹ + char* value = NULL; + ICS_ask_attribute_value(ico_tag, "״", &value); + if (value != NULL) { + int id = attrMap["״"]; + getClassValue(value, id, &cgField1); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, ";", &value); + if (value != NULL) { + int id = attrMap[";"]; + getClassValue(value, id, &cgField2); + DOFREE(value); + } + ICS_ask_attribute_value(ico_tag, "Ϲ", &value); + if (value != NULL) { + int id = attrMap["Ϲ"]; + getClassValue(value, id, &cgField3); + DOFREE(value); + } + if (strcmp("IN01", classCode) == 0 || strcmp("IN02", classCode) == 0 || strcmp("IN53", classCode) == 0) { + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s'", + itemType, cgField1); + } + //20250721 1ƥɹʱƥBIPϷࣻ + else if (strcmp("IN03", classCode) == 0 || strcmp("IN04", classCode) == 0) { + + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s' and PFIELDVALUE01= '%s'", + itemType, cgField1, cgField2, classCode); + } + else { + sprintf(cgSql, + "select PCGCODE,PFIELDVALUE04 from PLM_ERP_CG_TABLE where PTYPE= '%s' and PFIELDVALUE02= '%s' and PFIELDVALUE03= '%s' and PFIELDVALUE01= '%s'", + itemType, cgField1, cgField2, classCode); + } + } + + int cgOutputColumn = 0, cgOutputValueCount = 0; + + char*** cgOutputValue = NULL; + + + + + if (strcmp("", cgSql) != 0) { + WriteLog("ʾ:cgSql==%s\n", cgSql); + if (QuerySQLNoInputParam(cgSql, &cgOutputColumn, &cgOutputValueCount, &cgOutputValue) == -1 || cgOutputValueCount == 0) + { + if (cgOutputValue != NULL) { + for (int i1 = 0; i1 < cgOutputValueCount; i1++) { + for (int i2 = 0; i2 < cgOutputColumn; i2++) { + DOFREE(cgOutputValue[i1][i2]); + } + DOFREE(cgOutputValue[i1]); + } + DOFREE(cgOutputValue); + } + WriteLog("I2 => C=%d,R=%d\n", cgOutputColumn, cgOutputValueCount); + cgOutputColumn = 0; + cgOutputValueCount = 0; + cgOutputValue = NULL; + WriteLog("ʾ:ɹѯ ʧ, %s \n", cgSql); + if (QuerySQLNoInputParam(cgSql2, &cgOutputColumn, &cgOutputValueCount, &cgOutputValue) == -1) + { + WriteLog("ʾ:ɹѯ2 ʧ, %s \n", cgSql2); + } + } + WriteLog("cgOutputValueCount=%d\n", cgOutputValueCount); + WriteLog("cgOutputColumn=%d\n", cgOutputColumn); + + /*if (cgOutputValueCount <= 0) { + string errMsg = ""; + errMsg.append(itemId1); + errMsg.append("ɹѯʧ,PLM_ERP_CG_TABLE"); + EMH_store_error_s2(EMH_severity_error, 919031, errMsg.c_str(), "ʧ"); + return EPM_nogo; + }*/ + + //free(sql); + //20250721 ӷָж + if (cgField3 != NULL && (strcmp("IN01", classCode) == 0 || strcmp("IN03", classCode) == 0 || strcmp("IN04", classCode) == 0 || strcmp("IN07", classCode) == 0 || strcmp("IN52", classCode) == 0)) { + WriteLog("111\n"); + WriteLog("cgField3======%s\n", cgField3); + char result[200]; // ȷresult㹻Դ洢 + // ڶַλ + size_t second_char_pos = 2; + if (strstr(cgField3, "") != NULL) + { + // ȡڶַ֮ + strcpy(result, cgField3 + second_char_pos); + WriteLog("1\n"); + } + if (strstr(cgField3, "") != NULL) + { + // ȡڶַ֮ + strcpy(result, cgField3 + second_char_pos); + WriteLog("2\n"); + } + WriteLog("cgField3====%s\n", result); + double result_num = atof(result); // תΪ + if (cgOutputValueCount > 0) { + cgCode = cgOutputValue[0][0]; + limit_value = cgOutputValue[0][1]; + WriteLog("ɹ====%s\n", cgCode); + WriteLog("ֵ====%s\n", limit_value); + if (limit_value != NULL + && strcmp(limit_value, "") != 0 + && strcmp(limit_value, " ") != 0) { + if (strstr(limit_value, "-") != NULL) + { + //-в֡ + int numCount = 0; + char** numChar = new char* [64]; + int valCount = 0; + char** valChar = new char* [64]; + //ַָ + split(limit_value, "-", numChar, &numCount); + split(cgCode, ",", valChar, &valCount); + for (int ii = 0; ii < numCount; ii++) + { + double int_value1 = atof(numChar[ii]); + if (result_num < int_value1) { + cgCode = valChar[ii]; + break; + } + else { + if (ii != numCount - 1) { + double int_value2 = atof(numChar[ii + 1]); + if (result_num < int_value2) { + cgCode = valChar[ii + 1]; + break; + } + } + else { + cgCode = valChar[numCount - 1]; + break; + } + } + } + DOFREE(numChar); + } + } + WriteLog("ɹ====%s\n", cgCode); + } + } + else { + WriteLog("222\n"); + if (cgOutputValueCount > 0) { + cgCode = cgOutputValue[0][0]; + } + /*if (true) { + return 0; + }*/ + WriteLog("333\n"); + } + if (object_name != NULL) { + DOFREE(object_name); + } + if (limit_value != NULL) { + DOFREE(limit_value); + } + } + + + if (factorys != NULL) { + DOFREE(factorys); + } + if (outputValue != NULL) { + DOFREE(outputValue); + } + if (field1 != NULL) { + DOFREE(field1); + } + if (field2 != NULL) { + DOFREE(field2); + } + if (cgField1 != NULL) { + DOFREE(cgField1); + } + if (cgField2 != NULL) { + DOFREE(cgField2); + } + if (cgField3 != NULL) { + DOFREE(cgField3); + } + } + if (factoryCode != NULL) { + strcat(parameters, "\"orgCode\":\""); + int fattrCount = 0; + char** fattrChar = new char* [128]; + WriteLog("factoryCode=============%s\n", factoryCode); + split(factoryCode, ",", fattrChar, &fattrCount); + + string factoryCodeStr = ""; + for (int g = 0; g < fattrCount; g++) { + + if (!strstr(factoryCodeStr.c_str(), fattrChar[g])) { + factoryCodeStr.append(fattrChar[g]); + factoryCodeStr.append(","); + } + } + WriteLog("factoryCodeStr.c_str()=============%s\n", factoryCodeStr.c_str()); + strcat(parameters, factoryCodeStr.c_str()); + if (organization != NULL && strcmp(organization,"") != 0) { + strcat(parameters, ","); + strcat(parameters, organization); + } + strcat(parameters, "\","); + } + strcat(parameters, "\"manageClassCode\":\""); + if (classCode != NULL) { + strcat(parameters, classCode); + } + strcat(parameters, "\","); + strcat(parameters, "\"purchaseClassCode\":\""); + if (cgCode != NULL) { + strcat(parameters, cgCode); + } + else { + strcat(parameters, ""); + } + strcat(parameters, "\","); + // ʹõmap + int index = 0; + for (std::map::iterator it = propMap.begin(); it != propMap.end(); ++it) { + string key = it->first; + string attr = it->second; + WriteLog("key: %s \n", key.c_str()); + WriteLog("attr: %s \n", attr.c_str()); + if (strcmp("orgCode", key.c_str()) == 0) { + index++; + continue; + } + if (strstr(attr.c_str(), ".") != NULL) + { + int attrCount = 0; + char** attrChar = new char* [128]; + char* attrName = new char[2048];//㹻 + strcpy(attrName, attr.c_str()); + WriteLog("attrName: %s \n", attrName); + //ַָ + split(attrName, ".", attrChar, &attrCount); + WriteLog("attrCount=========%d\n", attrCount); + char* value = NULL; + if (strcmp("rev", attrChar[0]) == 0) { + //λ⴦ + if (strcmp("uom_tag", attrChar[1]) == 0) + { + //tag_t item = NULLTAG; + //ITKCALL(ITEM_ask_item_of_rev(attachments[i], &item)); + //tag_t unitTag = NULLTAG; + //ITKCALL(AOM_ask_value_tag(item, attrChar[1], &unitTag)); + //if (unitTag != NULL) { + // ITKCALL(AOM_UIF_ask_value(unitTag, "object_string", &value)); + // WriteLog("uom_tag: %s \n", value); + // //λ + // // ضϷ൥λ㣺λLתWL֬ļλGM() תKGǧˣ;ֲģֹܼλGM()תT֣ + // if (className != NULL) { + // if (strcmp("", className) == 0 && strcmp("L()", value) == 0) + // { + // value = "WL()"; + // } + // else if (strcmp("֬", className) == 0 && strcmp("GM()", value) == 0) + // { + // value = "KG(ǧ)"; + // }if ((strcmp("ֲ", className) == 0 || strcmp("ֹ", className) == 0) && strcmp("GM()", value) == 0) + // { + // value = "T()"; + // } + // } + // strcat(parameters, "\""); + // strcat(parameters, key.c_str()); + // strcat(parameters, "\":\""); + // if (unitMap.find(value) != unitMap.end()) { + // strcat(parameters, unitMap[value].c_str()); + // } + // else { + // strcat(parameters, value); + // } + // strcat(parameters, "\""); + //} + //else { + // strcat(parameters, "\""); + // strcat(parameters, key.c_str()); + // strcat(parameters, "\":\""); + // if (punit != NULL) { + // strcat(parameters, punit); + // } + // strcat(parameters, "\""); + + //} + //if (item != NULL) { + // DOFREE(item); + //} + //if (unitTag != NULL) { + // DOFREE(unitTag); + //} + + + //20250721޸ 5λֶԭضתΪȫBIPȡϷձеĵλ + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (punit != NULL) { + strcat(parameters, punit); + } + strcat(parameters, "\""); + } + //⴦ + else if (strcmp("netWeight", key.c_str()) == 0) + { + strcat(parameters, "\"netWeightUnitCode\":\"KG\","); + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + WriteLog("value=============================%s\n", value); + if (value != NULL && strcmp("", value) != 0 && strcmp(value,"/") != 0) { + double dValue = std::stod(value); + dValue = dValue * 10000; + long lValue = static_cast(dValue); // תΪlong + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":"); + char netWeight[64] = "\0"; + sprintf(netWeight, "%d", lValue); + strcat(parameters, netWeight); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":0"); + } + } + //⴦ + else if (strcmp("material_status", key.c_str()) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + if (smzqMap.find(value) != smzqMap.end()) { + strcat(parameters, smzqMap[value].c_str()); + } + else { + strcat(parameters, value); + } + strcat(parameters, "\""); + } + //rb3_th ⴦ + else if (strcmp("rb3_th", attrChar[1]) == 0) + { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + WriteLog("rb3_th====%s\n", value); + + if (strstr(value, "XX-") || strstr(value, "SF-")) { + removeSubstringRelease(value, "XX-"); + removeSubstringRelease(value, "SF-"); + } + WriteLog("rb3_th===========%s\n", value); + + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, value); + strcat(parameters, "\""); + } + else { + ITKCALL(AOM_UIF_ask_value(attachments[i], attrChar[1], &value)); + + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, value); + strcat(parameters, "\""); + + } + } + //20250721 ȥ"" ƴӵ߼ + else { + if (ico_tag != NULLTAG) { + if (strstr(attrChar[1], "&") != NULL) + { + int attrNum = 0; + char** allAttrs = new char* [128]; + //ַָ + split(attrChar[1], "&", allAttrs, &attrNum); + WriteLog("---attrChar===========%s\n", attrChar[1]); + char values[256] = "";//ƴ + for (int i = 0; i < attrNum; i++) + { + if (attrMap.find(allAttrs[i]) != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, allAttrs[i], &value); + + WriteLog("---value===========%s\n", value); + WriteLog("---allAttrs[i]===========%s\n", allAttrs[i]); + + if (strcmp(allAttrs[i],"񶯼ٶ") == 0 || strcmp(allAttrs[i], "񶯵ȼ") == 0 || strcmp(allAttrs[i], "ٶ") == 0) { + if (value != NULL) { + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("---disValue1===========%s\n", disValue); + if (strcmp(disValue,"") == 0) { + strcat(values, ""); + } + else { + if (strstr(disValue, ":")) { + int mhNum = 0; + char** mhAttrs = new char* [128]; + //ַָ + split(disValue, ":", mhAttrs, &mhNum); + WriteLog("---mhAttrs===========%s\n", mhAttrs[0]); + strcat(values, mhAttrs[0]); + } + else { + + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("---disValue22===========%s\n", disValue); + strcat(values, disValue); + } + + } + + + DOFREE(disValue); + } + } + else { + if (value != NULL) { + int id = attrMap[allAttrs[i]]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("---disValue===========%s\n", disValue); + strcat(values, disValue); + DOFREE(disValue); + } + + } + + } + else { + strcat(values, ""); + } + } + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, values); + strcat(parameters, "\""); + DOFREE(allAttrs); + } + else { + //ּܰ⴦ + if (strcmp("CU0261", key.c_str()) == 0) + { + if (attrMap.find("ּܰ(mm)") != attrMap.end()) + { + attrChar[1] = "ּܰ(mm)"; + } + else if (attrMap.find("ѹּܰ(mm)") != attrMap.end()) + { + attrChar[1] = "ѹּܰ(mm)"; + } + else if (attrMap.find("ּܰ()") != attrMap.end()) + { + attrChar[1] = "ּܰ()"; + } + } + //ܷɫ⴦ + else if (strcmp("CU0262", key.c_str()) == 0) + { + if (attrMap.find("ܷɫ") != attrMap.end()) + { + //WriteLog("1111\n"); + attrChar[1] = "ܷɫ"; + } + else if (attrMap.find("ܷɫ(ֶ)") != attrMap.end()) + { + attrChar[1] = "ܷɫ(ֶ)"; + } + else if (attrMap.find("(ܷɫ)") != attrMap.end()) + { + attrChar[1] = "(ܷɫ)"; + } + } + //ܷ⴦ + else if (strcmp("CU0263", key.c_str()) == 0) + { + if (attrMap.find("ܷ") != attrMap.end()) + { + //WriteLog("2222\n"); + attrChar[1] = "ܷ"; + } + else if (attrMap.find("ܷ(ֶ)") != attrMap.end()) + { + attrChar[1] = "ܷ(ֶ)"; + } + else if (attrMap.find("(ܷ)") != attrMap.end()) + { + attrChar[1] = "(ܷ)"; + } + } + //WriteLog("attrChar[1] = %s \n", attrChar[1]); + if (attrMap.find(attrChar[1]) != attrMap.end()) + { + ICS_ask_attribute_value(ico_tag, attrChar[1], &value); + if (value != NULL && strcmp(value, "") != 0 && strcmp(value, " ") != 0) { + int id = attrMap[attrChar[1]]; + char* disValue; + getClassValue(value, id, &disValue); + /* WriteLog("id = %d \n", id); + WriteLog("disValue = %s \n", disValue);*/ + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, disValue); + strcat(parameters, "\""); + DOFREE(disValue); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + WriteLog("value: %s \n", value); + DOFREE(value); + DOFREE(attrChar); + DOFREE(attrName); + } + else { + if (strcmp("CU0266", key.c_str()) == 0 && strcmp("RB3_LBJRevision", itemType) == 0 && ico_tag != NULLTAG) + { + WriteLog("㲿⴦\n"); + char* value = NULL; + if (attrMap.find("") != attrMap.end()) + { + + ICS_ask_attribute_value(ico_tag, "", &value); + WriteLog(" : %s \n", value); + if (value != NULL && strcmp(value,"") != 0) { + int id = attrMap[""]; + char* disValue; + getClassValue(value, id, &disValue); + WriteLog("disValue : %s \n", disValue); + if (disValue != NULL && strcmp("C:", disValue) == 0) { + tag_t parentClass = NULLTAG; + char* parentClassId = NULL; + char* parentClassName = NULL; + ITKCALL(ICS_class_ask_parent(classId, &parentClass, &parentClassId)); + if (parentClass != NULLTAG) { + ITKCALL(ICS_ask_id_name(parentClass, &parentClassId, &parentClassName)); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\""); + strcat(parameters, parentClassName); + strcat(parameters, "\""); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(parentClass); + DOFREE(parentClassId); + DOFREE(parentClassName); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(disValue); + } + else { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + else + { + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + DOFREE(value); + }//⴦ + else if (strcmp("netWeight", key.c_str()) == 0) + { + strcat(parameters, "\"netWeightUnitCode\":\"KG\","); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":0"); + } + else + { + WriteLog("key: %s ĬΪֵ\n", key.c_str()); + strcat(parameters, "\""); + strcat(parameters, key.c_str()); + strcat(parameters, "\":\"\""); + } + } + if (index < propMap.size() - 1) + { + strcat(parameters, ","); + } + index++; + } + if (classId != NULL) { + DOFREE(classId); + } + if (ico_tag != NULL) { + DOFREE(ico_tag); + } + if (classCode != NULL) { + DOFREE(classCode); + } + if (cgCode != NULL) { + DOFREE(cgCode); + } + if (className != NULL) { + DOFREE(className); + } + if (organization != NULL) { + DOFREE(organization); + } + if (punit != NULL) { + DOFREE(punit); + } + strcat(parameters, "}"); + attrMap.clear(); + } + DOFREE(itemType); + DisConnServer(); + } + + strcat(parameters, "]"); + //WriteLog("parameters: %s\n", parameters); + //дļ + char data_file[SS_MAXPATHLEN] = ""; + strcat(data_file, tc_root_file); + strcat(data_file, "\\"); + strcat(data_file, date); + strcat(data_file, ".txt"); + WriteLog("data_file: %s\n", data_file); + ofstream file; + file.open(data_file); + file << parameters << endl; // ʹcoutͬķʽд + file.close(); + + string strResult; + + //cmdָ + char cmd[256] = ""; + strcpy(cmd, "java -jar \""); + strcat(cmd, tc_root_file); + strcat(cmd, "\\portal\\plugins\\"); + strcat(cmd, "RB_SendErp_New.jar"); + strcat(cmd, "\" "); + // + //cout << data_file << endl; + strcat(cmd, data_file); + //ݱ̵(@ָ) + strcat(cmd, "@WL"); + //WriteLog("·:\n%s\n", cmd); + char buf[8000] = { 0 }; + FILE* pf = NULL; + if ((pf = _popen(cmd, "r")) == NULL) { + WriteLog("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + + cout << strResult << endl; + unsigned int iSize = strResult.size(); + char errorMessage[100000] = "";//д뵽ļֵ + if (iSize > 0 && strResult[iSize - 1] == '\n' && strlen(parameters) > 0) + { + + strResult = strResult.substr(0, iSize - 1); + //WriteLog("·ʧ\n"); + //cout << strResult << endl; + + if (strstr(strResult.c_str(), "\"code\":200") != NULL) + { + WriteLog("·ɹ\n"); + + + } + else { + ifail = EPM_nogo; + strcat(errorMessage, strResult.c_str()); + + WriteLog("ʼ%d", user_cnt); + for (int i = 0; i < user_cnt; i++) { + char cmd[10240] = ""; // 64KB + char jarfile[512] = ""; + string mail_addr = mail_addrs[i]; + if(mail_addr.size() > 0){ + WriteLog(">> %d. ʼ[%s]", i + 1, mail_addr.c_str()); + sprintf(jarfile, "%s\\bin\\EMailSender.jar", getenv("TC_ROOT")); + strcpy_s(cmd, "java -jar "); + strcat_s(cmd, jarfile); + strcat_s(cmd, " \""); + strcat_s(cmd, mail_addr.c_str()); + strcat_s(cmd, "\" \"TeamCenterERP-ITEM\" \""); + strcat_s(cmd, job_name); + strcat_s(cmd, ":ʧ->"); + strcat_s(cmd, errorMessage); + strcat_s(cmd, "\""); + WriteLog("CMD%s", cmd); + system(cmd); + WriteLog("ִ"); + } + DOFREE(cmd); + } + + } + } + WriteLog("ifail: %d\n", ifail); + if (attachments != NULL) { + MEM_free(attachments); + } + if (pref_vals != NULL) { + MEM_free(pref_vals); + } + //if (tc_root_file != NULL) { + // MEM_free(tc_root_file); + //} + + + if (ifail == EPM_nogo){ + EMH_store_error_s1(EMH_severity_user_error, EMH_USER_error_base, errorMessage); + + } + + WriteLog("=========================·ERP rule release End===================\n"); + CloseLog(); + return ifail; +} \ No newline at end of file diff --git a/CONNOR_ITK/RB_testquery_ID.cpp b/CONNOR_ITK/RB_testquery_ID.cpp new file mode 100644 index 0000000..8bda2c9 --- /dev/null +++ b/CONNOR_ITK/RB_testquery_ID.cpp @@ -0,0 +1,69 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" +#include +#include +#include "ocilib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ITK_err 919821 +using namespace std; + +int RB_testquery_ID(EPM_action_message_t msg) +{ + int ifail = ITK_ok; + int attachments_num = 0; + tag_t rootTask = NULLTAG, * attachments = NULLTAG; + //ȡ + EPM_ask_root_task(msg.task, &rootTask); + //ȡĿ + EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments); + //ȡ + char* url = NULL, * name = NULL, * password = NULL; + char* argflag = NULL, * argvalue = NULL, * arg = NULL; + int arg_cnt = TC_number_of_arguments(msg.arguments); + + tag_t item; + //id + ITKCALL(ITEM_find_item("JCSY-000011", &item)); + if (item == NULL) { + // òѯһȡѯ + tag_t query_tag1 = NULLTAG; + ITKCALL(QRY_find2("...", &query_tag1)); + if (query_tag1 == NULLTAG) + { + printf("ûҵ [%s]ѯ\n", "..."); + return 0; + } + int querynum = 0; + tag_t* queryresults = NULLTAG; + char* quvalue[1]; + char* querykey[1]; + quvalue[0] = " ID"; + querykey[0] = "JCSY-000011"; + ITKCALL(QRY_execute(query_tag1, 1, quvalue, querykey, &querynum, &queryresults)); + if (querynum > 0) { + item = queryresults[0]; + } + } + if (item!=NULL) { + char* name; + AOM_ask_value_string(item, "object_string", &name); + printf("ҵ%s\n", name); + } + else { + printf("ûҵ\n"); + } +} + diff --git a/CONNOR_ITK/StringUtil.cxx b/CONNOR_ITK/StringUtil.cxx new file mode 100644 index 0000000..0a9132c --- /dev/null +++ b/CONNOR_ITK/StringUtil.cxx @@ -0,0 +1,252 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "epm_handler_common.h" + +#define DOFREE(obj) \ +{ \ + if(obj) \ + { \ + MEM_free(obj); \ + obj = NULL; \ + } \ +} +std::vector split(const std::string &str, const std::string &pattern) +{ + std::vector resVec; + + if ("" == str) + { + return resVec; + } + //ȡһ + std::string strs = str + pattern; + + size_t pos = strs.find(pattern); + size_t size = strs.size(); + + while (pos != std::string::npos) + { + std::string x = strs.substr(0, pos); + resVec.push_back(x); + strs = strs.substr(pos + pattern.size(), size); + pos = strs.find(pattern); + } + + return resVec; +}; +//ַָ +void split(char *src, const char *separator, char **dest, int *num) { + + vector resultVector = split(src, separator); + int count = 0; + for (auto result : resultVector) { + int nLen = strlen(result.c_str()); + char *pCh = new char[nLen + 1]; + strcpy(pCh, result.c_str()); + dest[count] = pCh; + ++count; + } + *num = count; + ///* + //src Դַ׵ַ(bufĵַ) + //separator ָķַָ + //dest ַ + //num ַָĸ + //*/ + //char *pNext; + //int count = 0; + //if (src == NULL || strlen(src) == 0) //ĵַΪջ򳤶Ϊ0ֱֹ + // return; + //if (separator == NULL || strlen(separator) == 0) //δֱַָָֹ + // return; + + + ////printf("ָǰַ=======================%s\n", src); + + //pNext = strtok(src, separator); //ʹ(char *)ǿת(Ȼдеıвָ) + //while (pNext != NULL) { + + + // //printf("ַָ=======================%s\n", pNext); + + // dest[count] = pNext; + // ++count; + // pNext = strtok(NULL, separator); //ʹ(char *)ǿת + //} + //*num = count; +} + +char* U2G(const char* utf8) +{ + + int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); + + wchar_t* wstr = new wchar_t[len + 1]; + memset(wstr, 0, len + 1); + + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len); + len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + + char* str = new char[len + 1]; + memset(str, 0, len + 1); + + WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); + + if (wstr) + { + delete[] wstr; + wstr = NULL; + } + return str; +} + +//void removeChar(char* str, char c) +//{ +// char *tmp = str; //tmpʱ洢strַ +// int i = 0; +// while (*tmp) //tmpַָĩβ\0ʱѭ +// { +// if (*tmp != c) //жַǷΪո񣬲򽫸ַ浽strУ +// { +// str[i++] = *tmp; +// } +// tmp++; +// } +// str[i] = '\0'; //ַýʶ +// //puts(str); //õַ +// //DOFREE(tmp); +//} + +/********************************************************************** +* ƣ gbk_strlen +* 㺬кֵַȣΪһַ +* Ҫַ +* +* ֵ ַ +* ˵ +* ޸ 汾 ޸ ޸ +* ----------------------------------------------- +* +***********************************************************************/ +int gbk_strlen(const char* str) +{ + const char* p = str; //pں + while (*p) //ǽ0ѭ + { + if (*p < 0 && (*(p + 1)<0 || *(p + 1) < 63)) //ĺ + { + str++; //strƶһλpƶƶ2λ˳ȼ1 + p += 2; + } + else + { + p++; //strpƶһλȼ1 + } + } + return p - str; //صַ֮ +} + +void stringToLenth(int value, int num, char ** result) +{ + string num_str = to_string(value); + if (num_str.size() > num) + { + num_str = num_str.substr(0, num); + } + else + { + while (num_str.size() < num) { + num_str = "0" + num_str; + } + } + char * resultValue = new char[num]; + strcpy(resultValue, num_str.c_str()); + *result = resultValue; +} + +bool count(vector values, char * value) +{ + for (auto referencedValue : values) { + if (strcmp(referencedValue, value) == 0) + { + return true; + } + } + return false; +} + +void split(std::string s, const char* delim, std::vector* ret) +{ + size_t last = 0; + size_t index = s.find(delim, last); + int size = strlen(delim); + while (index != std::string::npos) { + ret->push_back(s.substr(last, index - last)); + last = index + size; + index = s.find(delim, last); + } + if (index - last > 0) { + ret->push_back(s.substr(last, index - last)); + } +} + +bool isTypeOf(tag_t objtag, const char * type_name) { + tag_t type = NULLTAG; + TCTYPE_ask_object_type(objtag, &type); + tag_t item_type = NULLTAG; + TCTYPE_find_type(type_name, "", &item_type); + bool is_type = false; + if (item_type != NULLTAG) { + logical isok = FALSE; + TCTYPE_is_type_of(type, item_type, &isok); + if (isok) { + is_type = true; + } + } + return is_type; +} + +void vecToArray(vector &vec, char ***arr) +{ + (*arr) = (char **)MEM_alloc(vec.size()*sizeof(char *)); + for (auto i = 0; i user) +{ + //ȡ + int perform_count = 0; + tag_t * perform_attaches = NULLTAG; + AOM_ask_value_tags(current_task, "valid_signoffs", &perform_count, &perform_attaches); + + for (int i = 0; i < user.size(); i++) { + int signoff_cnt = 0; + tag_t * signoffs = NULLTAG; + tag_t tmp_select_signoff_task = NULLTAG; + if (user[i] != NULLTAG) + { + bool isHave = false; + //жǷѰָԱ + if (perform_count > 0) + { + for (int j = 0; j < perform_count; j++) + { + tag_t user_tag = NULLTAG; + AOM_ask_value_tag(perform_attaches[j], "fnd0Assignee", &user_tag); + if (user_tag != NULL_TAG) { + //жuserIDǷͬ + char * user_id = NULL; + SA_ask_user_identifier2(user_tag, &user_id); + char * checkUser_id = NULL; + SA_ask_user_identifier2(user[i], &checkUser_id); + if (strcmp(user_id, checkUser_id) == 0) + { + isHave = true; + DOFREE(user_id); + DOFREE(checkUser_id); + break; + } + DOFREE(user_id); + DOFREE(checkUser_id); + } + } + } + if (isHave) + { + DOFREE(signoffs); + continue; + } + + EPM_ask_sub_task(current_task, EPM_select_signoff_team_task, &tmp_select_signoff_task); + if (tmp_select_signoff_task != NULLTAG) + { + EPM_create_adhoc_signoff(tmp_select_signoff_task, user[i], &signoff_cnt, &signoffs); + EPM_set_adhoc_signoff_selection_done(tmp_select_signoff_task, true); + //EPM_trigger_action(tmp_select_signoff_task, EPM_complete_action, ""); + } + else + { + //ִ + AOM_lock(current_task); + AOM_set_value_tag(current_task, "fnd0Performer", user[i]); + AOM_save(current_task); + AOM_unlock(current_task); + AOM_refresh(current_task, FALSE); + } + } + DOFREE(signoffs); + } + return true; +} + + +void TCFindItem(char * queryName, int n_entries,char ** qry_entries,char ** qry_values, int * n_found, tag_t ** dba_mbrs) +{ + tag_t query = NULLTAG; + QRY_find2(queryName, &query); + QRY_execute(query, n_entries, qry_entries, qry_values, n_found, dba_mbrs); +} + + + +char * getLovKey(int theAttrId, char * value) +{ + char* key_lov_name; + int options = 0; + int n_lov_entries = 0; + char** lov_keys; + char** lov_values; + logical* deprecated_staus; + char* owning_site; + int n_shared_sites = 0; + char** shared_sites; + char* format = NULL; + ICS_attribute_ask_property(theAttrId, "FORMAT1", &format); + + ICS_keylov_get_keylov(format, &key_lov_name, &options, &n_lov_entries, &lov_keys, &lov_values, &deprecated_staus, + &owning_site, &n_shared_sites, &shared_sites); + if (n_lov_entries > 0) { + for (int q = 0; q < n_lov_entries; q++) { + if (strcmp(value, lov_values[q]) == 0) { + + printf("lov_values[q]%s\n", value); + printf("lov_keys[q]%s\n", lov_keys[q]); + + value = lov_keys[q]; + break; + } + } + } + return value; +} + +char * getClassProperty(tag_t item, char * propertyName) +{ + char * result = ""; + tag_t ico_tag = NULLTAG; + ICS_ask_classification_object(item, &ico_tag); + int theAttributeCount, *theAttributeIds, *theAttributeValCounts; + char ***theAttributeValues; + ICS_ico_ask_attributes(ico_tag, &theAttributeCount, &theAttributeIds, &theAttributeValCounts, &theAttributeValues); + for (int t = 0; t < theAttributeCount; t++) { + char theAttributeId[20] = "\0"; + printf("theAttributeIds=%d ,theAttributeValCounts=%d\n", theAttributeIds[t], theAttributeValCounts[t]); + sprintf(theAttributeId, "%d", theAttributeIds[t]); + if (theAttributeValCounts[t]>0 && strcmp(theAttributeId, propertyName) == 0) { + printf("icoLineCode=%s\n", theAttributeValues[t][0]); + result = theAttributeValues[t][0];//getLovKey(theAttributeIds[t], theAttributeValues[t][0]); + break; + } + } + return result; +} + + +void TCGetPropertyValue(tag_t item,char * type,char * propertyName,char ** propertyValue) +{ + //жǷ. + if (strstr(propertyName, ".") != NULL) + { + //ݵȺŲֵ + int itemPropertyCount = 0; + char ** itemPropertyChar = new char *[64]; + //ַָ + split(propertyName, ".", itemPropertyChar, &itemPropertyCount); + + char * itemAddress = itemPropertyChar[0]; + + if (strcmp(type, "Revision") == NULL) + { + //ǰ汾 + if (strcmp(itemAddress, "item") == 0) + { + ITEM_ask_item_of_rev(item, &item); + } + else if (strcmp(itemAddress, "revMaster") == 0) + { + tag_t master_form_rel_type = NULLTAG, *form_list = NULLTAG; + int form_count = 0; + //ȡ汾 + GRM_find_relation_type(TC_master_form_rtype, &master_form_rel_type); + GRM_list_secondary_objects_only(item, master_form_rel_type, &form_count, &form_list); + if (form_count == 0) + { + printf("δҵform,..."); + } + else + { + item = form_list[form_count - 1]; + } + DOFREE(form_list); + } + //жϲֳǷ2 + if (itemPropertyCount > 2) + { + //ҹϵ + for (int i = 1; i < itemPropertyCount - 1; i++) + { + AOM_ask_value_tag(item, itemPropertyChar[i], &item); + } + } + if (strcmp(itemAddress, "class") == 0) + { + *propertyValue = getClassProperty(item, itemPropertyChar[itemPropertyCount - 1]); + } + else + { + if (item == NULL_TAG) + { + *propertyValue = ""; + } + else + { + AOM_UIF_ask_value(item, itemPropertyChar[itemPropertyCount - 1], propertyValue); + } + } + } + else if (strcmp(type, "BOMLine") == NULL) + { + tag_t revisions = NULLTAG; + + AOM_ask_value_tag(item, "bl_line_object", &revisions); + //Ƕ + if (strcmp(itemAddress, "item") == 0) + { + ITEM_ask_item_of_rev(revisions, &item); + } + else if (strcmp(itemAddress, "rev") == 0) + { + item = revisions; + } + else if (strcmp(itemAddress, "revMaster") == 0) + { + tag_t master_form_rel_type = NULLTAG, *form_list = NULLTAG; + int form_count = 0; + //ȡ汾 + GRM_find_relation_type(TC_master_form_rtype, &master_form_rel_type); + GRM_list_secondary_objects_only(revisions, master_form_rel_type, &form_count, &form_list); + if (form_count == 0) + { + printf("δҵform,..."); + } + else + { + item = form_list[form_count - 1]; + } + DOFREE(form_list); + } + //жϲֳǷ2 + if (itemPropertyCount > 2) + { + //ҹϵ + for (int i = 1; i < itemPropertyCount - 1; i++) + { + AOM_ask_value_tag(item, itemPropertyChar[i], &item); + } + } + if (strcmp(itemAddress, "class") == 0) + { + *propertyValue = getClassProperty(revisions, itemPropertyChar[itemPropertyCount - 1]); + } + else + { + if (item == NULL_TAG) + { + *propertyValue = ""; + } + else + { + AOM_UIF_ask_value(item, itemPropertyChar[itemPropertyCount - 1], propertyValue); + } + } + } + else if (strcmp(type, "Item") == NULL) + { + tag_t revisions = NULLTAG; + + ITEM_ask_latest_rev(item, &revisions); + //Ƕ + if (strcmp(itemAddress, "rev") == 0) + { + item = revisions; + } + else if (strcmp(itemAddress, "revMaster") == 0) + { + tag_t master_form_rel_type = NULLTAG, *form_list = NULLTAG; + int form_count = 0; + //ȡ汾 + GRM_find_relation_type(TC_master_form_rtype, &master_form_rel_type); + GRM_list_secondary_objects_only(revisions, master_form_rel_type, &form_count, &form_list); + if (form_count == 0) + { + printf("δҵform,..."); + } + else + { + item = form_list[form_count - 1]; + } + DOFREE(form_list); + } + //жϲֳǷ2 + if (itemPropertyCount > 2) + { + //ҹϵ + for (int i = 1; i < itemPropertyCount - 1; i++) + { + AOM_ask_value_tag(item, itemPropertyChar[i], &item); + } + } + + if (strcmp(itemAddress, "class") == 0) + { + *propertyValue = getClassProperty(revisions, itemPropertyChar[itemPropertyCount - 1]); + } + else + { + if (item == NULLTAG) + { + *propertyValue = ""; + } + else + { + AOM_UIF_ask_value(item, itemPropertyChar[itemPropertyCount - 1], propertyValue); + //char * type = NULL; + //AOM_ask_value_string(item, "object_type", &type); + ////ȡ + //tag_t tAttrID = NULLTAG; + //POM_attr_id_of_attr(itemPropertyChar[itemPropertyCount - 1], type, &tAttrID); + //if (tAttrID == NULLTAG) + //{ + // *propertyValue = ""; + //} + //else + //{ + // AOM_ask_value_string(item, itemPropertyChar[itemPropertyCount - 1], propertyValue); + //} + } + } + } + } + else + { + *propertyValue = propertyName; + } +} + +void BOMSendToWeixin(char * userId, tag_t rootTask_tag, string message) +{ + string jsonStr("{\\\"touser\\\":\\\""), strResult; + jsonStr.append(userId); + if (rootTask_tag != NULLTAG) + { + jsonStr.append("\\\",\\\"msgtype\\\":\\\"text\\\",\\\"agentid\\\":1000060,\\\"text\\\":{\\\"content\\\":\\\"BOM͵ERPʧܡ\\n̷ߣ"); + //ȡ̷ + tag_t owning_user = NULLTAG; + char * owning_id = NULL, *process_name = NULL; + AOM_ask_owner(rootTask_tag, &owning_user); + SA_ask_user_identifier2(owning_user, &owning_id); + jsonStr.append(owning_id); + jsonStr.append("\\nƣ"); + //ȡ + EPM_ask_name2(rootTask_tag, &process_name); + jsonStr.append(process_name); + + DOFREE(owning_id); + DOFREE(process_name); + } + else + { + jsonStr.append("\\\",\\\"msgtype\\\":\\\"text\\\",\\\"agentid\\\":1000060,\\\"text\\\":{\\\"content\\\":\\\"ʹò˵BOM͵ERPʧܡ\\n"); + } + + jsonStr.append("\\n쳣־"); + jsonStr.append(message); + jsonStr.append(""); + jsonStr.append("\\\"}}"); + char toJar[1000] = ""; + strcat(toJar, "java -jar "); + strcat(toJar, "C:\\PLM\\sendToWeixin.jar "); + strcat(toJar, jsonStr.c_str()); + //system(toJar); + //_popen(toJar, "r"); + + char buf[8000] = { 0 }; + FILE *pf = NULL; + if ((pf = _popen(toJar, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + cout << strResult << endl; +} + +void itemSendToWeixin(char * userId, tag_t rootTask_tag, string message) +{ + string jsonStr("{\\\"touser\\\":\\\""), strResult; + jsonStr.append(userId); + jsonStr.append("\\\",\\\"msgtype\\\":\\\"text\\\",\\\"agentid\\\":1000060,\\\"text\\\":{\\\"content\\\":\\\"Ϸ͵ERPʧܡ\\n̷ߣ"); + //ȡ̷ + tag_t owning_user = NULLTAG; + char * owning_id = NULL, *process_name = NULL; + AOM_ask_owner(rootTask_tag, &owning_user); + SA_ask_user_identifier2(owning_user, &owning_id); + jsonStr.append(owning_id); + jsonStr.append("\\nƣ"); + //ȡ + EPM_ask_name2(rootTask_tag, &process_name); + jsonStr.append(process_name); + jsonStr.append("\\n쳣־"); + jsonStr.append(message); + jsonStr.append(""); + jsonStr.append("\\\"}}"); + char toJar[1000] = ""; + strcat(toJar, "java -jar "); + strcat(toJar, "C:\\PLM\\sendToWeixin.jar "); + strcat(toJar, jsonStr.c_str()); + //system(toJar); + //_popen(toJar, "r"); + + char buf[8000] = { 0 }; + FILE *pf = NULL; + if ((pf = _popen(toJar, "r")) == NULL) { + printf("ӿڷ:\n%s", "1"); + } + + while (fgets(buf, sizeof buf, pf)) { + strResult += buf; + } + _pclose(pf); + cout << strResult << endl; + DOFREE(owning_id); + DOFREE(process_name); +} + +void GetFiles(string path, vector& files) +{ + //ļ + long hFile = 0; + //ļϢ + struct _finddata_t fileinfo; + std::string p; + if ((hFile = _findfirst(p.assign(path).append("/*").c_str(), &fileinfo)) != -1) + { + do + { + //Ŀ¼,֮ + //,б + if ((fileinfo.attrib & _A_SUBDIR)) + { + if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) + GetFiles(p.assign(path).append("/").append(fileinfo.name), files); + } + else + { + files.push_back(p.assign(path).append("/").append(fileinfo.name)); + } + } while (_findnext(hFile, &fileinfo) == 0); + _findclose(hFile); + } +} + +LPCWSTR stringToLPCWSTR(std::string orig) +{ + /*size_t origsize = orig.length() + 1; + const size_t newsize = 100; + size_t convertedChars = 0; + wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1)); + mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE); + + return wcstring;*/ + int len; + int slength = (int)orig.length() + 1; + len = MultiByteToWideChar(CP_ACP, 0, orig.c_str(), slength, 0, 0); + wchar_t* buf = new wchar_t[len]; + MultiByteToWideChar(CP_ACP, 0, orig.c_str(), slength, buf, len); + //std::wstring r(buf); + ///delete[] buf; + + //LPCWSTR result = r.c_str(); + return buf; +} + +const char * inputFileToFtp(char * filePath) +{ + string ftpFilePath = NULL; + //ftpַ + string ftpSvrIp = "10.18.1.105"; + //ftp˿ + int port = 21; + //û + string userName = "Administrator"; + //û + string password = "PlmTst_8023"; + //ϴļԴ· + string sourceFilePath = filePath; + //ϴļĿ· + string resultFilePath = "/λSOPļ/"; + string desFilePath = "./λSOPļ/"; + + vector files; + + //жϴļļбʶ + int size = 0; + if (sourceFilePath.find(".") == string::npos) + { + //ȡļļ + GetFiles(sourceFilePath, files); + char str[30]; + size = files.size(); + } + HINTERNET hint = NULL; + HINTERNET hftp = NULL; + do { + hint = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); + if (hint == NULL) + { + break; + } + //ftp + hftp = InternetConnect(hint, stringToLPCWSTR(ftpSvrIp), port, stringToLPCWSTR(userName), stringToLPCWSTR(password), INTERNET_SERVICE_FTP, 0, 0); + if (hftp == NULL) + { + break; + } + //Ŀ·ڣһһ + //Ŀ·ʽΪ:"./dir/dir1/.../" + int pos = 1; + string tempPath; + while (pos>0) + { + // ӵڶ/ʼҵĿ·еġ/λ + pos = desFilePath.find_first_of('/', pos + 1); + if (pos == -1) + break; + tempPath = desFilePath.substr(0, pos + 1); + if (_access(tempPath.c_str(), 0) == -1) + { + FtpCreateDirectory(hftp, stringToLPCWSTR(tempPath)); + } + } + + //FtpSetCurrentDirectoryһֱһdesFilePath·Ƿ񴴽ɹԴֱܷӷftp + if (FtpSetCurrentDirectory(hftp, stringToLPCWSTR(desFilePath))) + { + //ϴļԴΪһļ + if (0 == size) + { + //ȡϴ·еļ + int pos = sourceFilePath.find_last_of('/'); + string desfilename = sourceFilePath.substr(pos + 1); + int i = FtpPutFile(hftp, stringToLPCWSTR(sourceFilePath), stringToLPCWSTR(desfilename), FTP_TRANSFER_TYPE_BINARY, 0); + } + //ϴļԴΪļ + else + { + for (int i = 0; i < size; i++) + { + std::string tempFilePath = files[i].c_str(); + //ȡϴ·еļ + int pos = tempFilePath.find_last_of('/'); + string desfilename = tempFilePath.substr(pos + 1); + //desfilename = desFilePath + desfilename; + int result = FtpPutFile(hftp, stringToLPCWSTR(tempFilePath), stringToLPCWSTR(desfilename), FTP_TRANSFER_TYPE_ASCII, 0); + + if (result == 0) + { + printf("ϴļʧܣ\n"); + return NULL; + } + else + { + ftpFilePath = "FTP://" + ftpSvrIp + resultFilePath + desfilename; + } + } + } + } + } while (0); + + InternetCloseHandle(hftp); + InternetCloseHandle(hint); + + if (ftpFilePath.length() > 0) + { + cout << "ϴļ" << endl; + } + + return ftpFilePath.c_str(); +} + +char * getLineCode(char * lineCode) +{ + char * result = "ALL"; + int theCount1; + char **theICOUIDs, **theICOIds, **theClassIds, **theWSOUIDs; + tag_t *theICOTags, *theWSOTags; + ICS_class_ask_icos("ֵ", "", &theCount1, &theICOTags, &theICOUIDs, &theICOIds, &theClassIds, &theWSOTags, &theWSOUIDs); + printf("theCount1=%d\n", theCount1); + int theAttributeCount, *theAttributeIds, *theAttributeValCounts; + char ***theAttributeValues; + + for (int m = 0; m < theCount1; m++) + { + ICS_ico_ask_attributes(theICOTags[m], &theAttributeCount, &theAttributeIds, &theAttributeValCounts, &theAttributeValues); + printf("theICOIds=%s,theICOUID==%s\n", theICOIds[m], theICOUIDs[m]); + + char * icoLineCode = NULL; + char * icoERPCode = NULL; + + for (int t = 0; t < theAttributeCount; t++) { + char theAttributeId[20] = "\0"; + printf("theAttributeIds=%d ,theAttributeValCounts=%d\n", theAttributeIds[t], theAttributeValCounts[t]); + sprintf(theAttributeId, "%d", theAttributeIds[t]); + if (theAttributeValCounts[t]>0 && strcmp(theAttributeId,"1002") == 0) { + printf("icoLineCode=%s\n", theAttributeValues[t][0]); + icoLineCode = theAttributeValues[t][0]; + } + else if (theAttributeValCounts[t]>0 && strcmp(theAttributeId, "1101") == 0) { + printf("icoERPCode=%s\n", theAttributeValues[t][0]); + icoERPCode = theAttributeValues[t][0]; + } + } + if (strcmp(lineCode, icoLineCode) == 0 && icoERPCode != NULL && strcmp(icoERPCode, "") != 0) + { + result = icoERPCode; + break; + } + + } + return result; +} + +char* removeSpaces(char* str) { + int i, j; + // ַеҷǿַƵǰλ + for (i = j = 0; str[i] != '\0'; i++) + if (str[i] != ' ') + str[j++] = str[i]; + + // ĩβ'\0'ַ + str[j] = '\0'; + return str; +} + +char* removeChar(char* str, char charToRemove) { + char* newStr = str; + char* p = str; + while (*p) { + if (*p != charToRemove) { + *newStr++ = *p; + } + p++; + } + *newStr = '\0'; // ַֹ + return str; +} + +void removeFirstFourChars(char* str) { + if (str == nullptr) return; + char* newStart = std::next(str, 4); // ȡµʼλ + std::copy(newStart, str + std::strlen(str), str); // ʣַ + *std::strrchr(str, '\0') = '\0'; // ַĩβ +} + +bool startsWith(const char* str, char first, char second) { + return str && str[0] == first && str[1] == second; +} + +char* getFirstStr(const char* str, int index) { + if (str == nullptr) { + return nullptr; + } + int length = strlen(str); + if (length <= index) { + // µַ + char* result = new char[length + 1]; + strcpy(result, str); + return result; + } + else { + // µַǰĸַ + char* result = new char[index + 1]; + strncpy(result, str, index); + result[index] = '\0'; // ַ + return result; + } +} + +//ȡ +void getClassValue(char* value, int id, char** disValue) { + //printf("===================================\n"); + //printf("ȡ ʼ\n"); + //printf("===================================\n"); + char* format = NULL; + ITKCALL(ICS_attribute_ask_property(id, "FORMAT1", &format)); + //printf(">> Format: %s\n", format); + if (format != NULL && strcmp("", format) != 0 && strcmp(" ", format) != 0) { + char* key_lov_name; + int options = 0; + int n_lov_entries = 0; + char** lov_keys; + char** lov_values; + logical* deprecated_staus; + char* owning_site; + int n_shared_sites = 0; + char** shared_sites; + ICS_keylov_get_keylov(format, &key_lov_name, &options, &n_lov_entries, &lov_keys, &lov_values, &deprecated_staus, + &owning_site, &n_shared_sites, &shared_sites); + //printf(">> ֵ: %d\n", n_lov_entries); + if (n_lov_entries == 0) { + *disValue = value; + } + else { + for (int j = 0; j < n_lov_entries; j++) { + if (strcmp(value, lov_keys[j]) == 0) { + //printf("lovѡֵ=>:[%s]\n", lov_values[j]); + *disValue = lov_values[j]; + break; + } + } + if (key_lov_name != NULL) { + DOFREE(key_lov_name); + } + if (lov_keys != NULL) { + DOFREE(lov_keys); + } + if (lov_values != NULL) { + DOFREE(lov_values); + } + if (deprecated_staus != NULL) { + DOFREE(deprecated_staus); + } + if (owning_site != NULL) { + DOFREE(owning_site); + } + if (shared_sites != NULL) { + DOFREE(shared_sites); + } + } + } + if (format != NULL) { + DOFREE(format); + } + //printf("===================================\n"); + //printf("ȡ \n"); + //printf("===================================\n"); +} \ No newline at end of file diff --git a/CONNOR_ITK/connor_custom_main.cxx b/CONNOR_ITK/connor_custom_main.cxx new file mode 100644 index 0000000..978a37c --- /dev/null +++ b/CONNOR_ITK/connor_custom_main.cxx @@ -0,0 +1,44 @@ + + +#pragma warning (disable: 4819) + + +#include +#include +#include "epm_register_handler.h" +#include "epm_handler_common.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + + DLLAPI int rb_register_callbacks() + { + int ifail = ITK_ok; + ifail = CUSTOM_register_exit( + "rb", + "USERSERVICE_register_methods", + (CUSTOM_EXIT_ftn_t)USERSERVICE_custom_register_methods); + + + ifail = CUSTOM_register_exit( + "rb", + "USER_gs_shell_init_module", + (CUSTOM_EXIT_ftn_t)CUST_init_module); + + return ifail; + } + +#ifdef __cplusplus +} +#endif + + + + +/** +* @} +*/ \ No newline at end of file diff --git a/CONNOR_ITK/connor_itk_util.cpp b/CONNOR_ITK/connor_itk_util.cpp new file mode 100644 index 0000000..69cb04e --- /dev/null +++ b/CONNOR_ITK/connor_itk_util.cpp @@ -0,0 +1,596 @@ +#include +#include +#ifdef WIN32 +#include +#include +#else +#include +#endif +#include "connor_itk_util.h" +#include +#include + +#define ARGS_LENGTH 200 +#define ARGS_NAME_DEBUG "-debug" +#define DEBUG "-debug=" +#define MAX_PRINTLINE_LENGTH 20000 +#define MAX_PATH_LENGTH 2000 +#define MAX_ARGUMENT_LENGTH 400 +#define MAX_FILE_EXT_LENGTH 10 +#define TRUE_FLAG 1 +#define FALSE_FLAG 0 +#define DETAILLOG 1 + +void ECHO(char* format, ...) +{ + //if( !YFJC_OPT_DEBUG ) + // return; + + char msg[4096]; + va_list args; + + va_start(args, format); + vsprintf(msg, format, args); + va_end(args); + + printf(msg); + TC_write_syslog(msg); +} + +FILE* logFile = NULL; + +/*=============================================================================* + * FUNCTION: current_time + * PURPOSE : get the current datetime + * INPUT: + * date_t* date_tag // current date time tag + * + * RETURN: + * void + *============================================================================*/ +void current_time(date_t* date_tag) +{ + time_t ltime; + struct tm* today; + + // Set time zone from TZ environment variable. If TZ is not set, + // the operating system is queried to obtain the default value + // for the variable. + // + //_tzset(); + + // Get UNIX-style time and display as number and string. + time(<ime); + + today = localtime(<ime); + date_tag->year = today->tm_year + 1900; + date_tag->month = today->tm_mon; + date_tag->day = today->tm_mday; + date_tag->hour = today->tm_hour; + date_tag->minute = today->tm_min; + date_tag->second = today->tm_sec; +} +/*=============================================================================* + * FUNCTION: CreateLogFile + * PURPOSE : create log file + * INPUT: + * char* FunctionName // the funtion which need to create log file + * FILE** logFile // out: the log file pointer + * + * RETURN: + * void + *============================================================================*/ +void CreateLogFile(char* FunctionName, char** fullname) +{ + int i = 0, ifail = ITK_ok; + //date_t status_now; + //char* date_string = NULL; + char date_string[MAX_PATH_LENGTH]; + char logFileDir[MAX_PATH_LENGTH]; + char logFileName[MAX_PATH_LENGTH]; + + char* session_uid = NULL; + tag_t session_tag = NULLTAG; + time_t now; + struct tm* p; + + time(&now); + + logFile = NULL; + + p = localtime(&now); + + memset(date_string, 0, sizeof(date_string)); + sprintf(date_string,"%4d%02d%02d%02d%02d%02d",1900+p->tm_year,p->tm_mon+1 ,p->tm_mday ,p->tm_hour,p->tm_min ,p->tm_sec ); + //sprintf(date_string, "%4d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday); + + memset(logFileDir, 0, sizeof(logFileDir)); + memset(logFileName, 0, sizeof(logFileName)); + //get log dir + sprintf(logFileDir, "%s", getenv("TEMP")); + printf("\n log file dir: %s\n", logFileDir); + //try to change dir to TC_USER_LOG_DIR + if (chdir(logFileDir) != ITK_ok) + { + + memset(logFileDir, 0, sizeof(logFileDir)); + sprintf(logFileDir, "%s", getenv("TC_LOG")); + printf("\n TC_USER_LOG_DIR invalide, log file dir: %s\n", logFileDir); + if (chdir(logFileDir) != ITK_ok) + { + //still can not change to log dir + printf("!*ERROR*!: Failed to change dir to TC_USER_LOG_DIR\n"); + goto CLEANUP; + } + } + + + POM_ask_session(&session_tag); + ITK__convert_tag_to_uid(session_tag, &session_uid); + + + sprintf(logFileName, "%s_%s.log", FunctionName, date_string); + printf("log file name: %s\n", logFileName); + + *fullname = (char*)MEM_alloc(sizeof(char) * 512); + sprintf(*fullname, "%s\\%s", logFileDir, logFileName); + + + logFile = fopen(logFileName, "a"); + +CLEANUP: + //DOFREE(date_string); + DOFREE(session_uid); +} + + +/*=============================================================================* + * FUNCTION: WriteLog + * PURPOSE : write log, if debug log File not null, write log message to log File + * INPUT: + * const char* format // debug message string + * + * RETURN: + * void + *============================================================================*/ +void WriteLog(const char* format, ...) +{ + va_list arg; + char tmp[MAX_PRINTLINE_LENGTH]; + + if (logFile) + { + //get the message + memset(tmp, 0, sizeof(tmp)); + va_start(arg, format); + vsprintf(tmp, format, arg); + va_end(arg); + + //----------print to command window for trace--------// + printf("%s\n", tmp); + + //print message to log file + fprintf(logFile, "%s\n", tmp); + fflush(logFile); + } + else + { + printf("*!Error!*: Log File Not Exist\n"); + } +} + +void CloseLog(void) +{ + if (logFile) + { + fclose(logFile); + logFile = NULL; + } +} + +char* getTime() { + time_t now; + struct tm* p; + char date_string[30]; + time(&now); + //logFile = NULL; + //current_time(&status_now); + p = localtime(&now); + memset(date_string, 0, sizeof(date_string)); + //sprintf(date_string, "%4d-%02d-%02d %02d:%02d:%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + sprintf(date_string, "%4d-%02d-%02d %02d-%02d-%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + char* dateC = (char*)malloc(sizeof(char) * (strlen(date_string) + 1)); + strcpy(dateC, date_string); + return dateC; +} + +string getUUid() +{ + GUID guid; + char buffer[64] = { 0 }; + if (CoCreateGuid(&guid)) + { + printf("create guid error\n"); + return ""; + } + //_snprintf(buffer, sizeof(buffer), "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, + // guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + sprintf_s(buffer, sizeof(buffer), + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + + return buffer; +} + +char* GbkToUtf8(const char* src_str) +{ + int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0); + wchar_t* wstr = (wchar_t*)MEM_alloc((len + 1) * sizeof(wchar_t)); + memset(wstr, 0, len + 1); + MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len); + len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); + char* str = (char*)MEM_alloc((len + 1) * sizeof(char)); + + memset(str, 0, len + 1); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); + return str; +} + +char* Utf8ToGbk(const char* src_str) +{ + int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0); + wchar_t* wszGBK = (wchar_t*)MEM_alloc((len + 1) * sizeof(wchar_t)); + memset(wszGBK, 0, len * 2 + 2); + MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len); + len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); + char* szGBK = (char*)MEM_alloc((len + 1) * sizeof(char)); + + memset(szGBK, 0, len + 1); + WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); + return szGBK; +} + +void starTime() { + time_t now; + struct tm* p; + time(&now); + p = localtime(&now); + WriteLog("start time %4d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); +} + +/** +* +* жijǷΪItemRevision +* +*/ +logical checkIsItemRevision(tag_t objtag) { + tag_t type = NULLTAG; + tag_t item_type = NULLTAG; + logical isItems = false; + ITKCALL(TCTYPE_ask_object_type(objtag, &type)); + ITKCALL(TCTYPE_find_type("ItemRevision", "", &item_type)); + if (item_type != NULLTAG) { + logical isok = FALSE; + ITKCALL(TCTYPE_is_type_of(type, item_type, &isok)); + if (isok) { + isItems = TRUE; + } + else { + isItems = FALSE; + } + } + return isItems; +} + +int checkIsInType(tag_t objtag, string parentType) { + tag_t type = NULLTAG; + tag_t item_type = NULLTAG; + ITKCALL(TCTYPE_ask_object_type(objtag, &type)); + ITKCALL(TCTYPE_find_type(parentType.c_str(), "", &item_type)); + if (item_type != NULLTAG) { + logical isok = FALSE; + ITKCALL(TCTYPE_is_type_of(type, item_type, &isok)); + if (isok) { + return 1; + } + else { + return 0; + } + } + return 0; +} + +int getPrefStrings(const char* preference, vector& pref_vec) +{ + int ifail = ITK_ok, i = 0, j = 0, k = 0, num = 0; + char** values; + ITKCALL(ifail = PREF_ask_char_values(preference, &num, &values)); + for (i = 0; i < num; i++) + { + pref_vec.push_back(values[i]); + } + DOFREE(values); + return ifail; +} +bool isTypeOf(tag_t objtag, const char* type_name) { + tag_t type = NULLTAG; + TCTYPE_ask_object_type(objtag, &type); + tag_t item_type = NULLTAG; + TCTYPE_find_type(type_name, "", &item_type); + bool is_type = false; + if (item_type != NULLTAG) { + logical isok = FALSE; + TCTYPE_is_type_of(type, item_type, &isok); + if (isok) { + is_type = true; + } + } + return is_type; +} + +void Split(string strArg, string spliter, vector& ans) +{ + ans.clear(); + size_t index0 = 0; + string one_arg; + if (strArg.find_first_not_of(' ') == string::npos) + strArg = ""; + int len = spliter.size(); + while (strArg.size() > 0) + { + index0 = strArg.find(spliter); + if (index0 != string::npos) + { + one_arg = strArg.substr(0, index0); + strArg = strArg.substr(index0 + len); + ans.push_back(one_arg); + if (strArg.size() == 0) { + ans.push_back(strArg); + } + } + else + { + ans.push_back(strArg); + break; + } + } +} + +string dealPre(tag_t attachment, char* item_id, char* form_name, char* deal_type,tag_t classificationObject,char* typePref) { + char** pre_values = NULL; + int valueNum = 0; + WriteLog("(char*)tableName.c_str()============%s\n", form_name); + PREF_ask_char_values(typePref, &valueNum, &pre_values); + if (pre_values == NULL) { + return ""; + } + WriteLog("1\n"); + tag_t item, * forms; + ITEM_ask_item_of_rev(attachment, &item); + WriteLog("2\n"); + int rev_cnt = 0; + ITKCALL(AOM_ask_value_tags(attachment, "IMAN_master_form_rev", &rev_cnt, &forms)); + char* item_type, * rev_type, * form_type; + WriteLog("3\n"); + ITKCALL(AOM_ask_value_string(attachment, "object_type", &rev_type)); + ITKCALL(AOM_ask_value_string(item, "object_type", &item_type)); + ITKCALL(AOM_ask_value_string(forms[0], "object_type", &form_type)); + printf("ͷֱΪ%s--------%s------%s\n", item_type, rev_type, form_type); + WriteLog("4\n"); + string sql; + + + + if (strcmp("update", deal_type) == 0) { + sql.append("UPDATE ["); + sql.append(form_name); + sql.append("] SET "); + for (int i = 0; i < valueNum; i++) + { + WriteLog("5\n"); + vector one; + vector two; + Split(pre_values[i], ".", one); + Split(one[1], "=", two); + char* temp_value = NULL; + sql.append("["); + sql.append(two[1]); + sql.append("]"); + if (strcmp("ItemID", two[1].c_str()) == 0) { + WriteLog("6\n"); + sql.append("='"); + if (strcmp(item_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(item, two[0].c_str(), &temp_value)); + } + else if (strcmp(rev_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(attachment, two[0].c_str(), &temp_value)); + } + else if (strcmp(form_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(forms[0], two[0].c_str(), &temp_value)); + } + else if (classificationObject != NULL && strcmp(one[0].c_str(),"classField") == 0) { + ICS_ask_attribute_value(classificationObject, two[0].c_str(), &temp_value); + } + if (temp_value != NULL) { + sql.append(temp_value); + + } + sql.append("',"); + } + else { + WriteLog("7\n"); + sql.append("='"); + if (strcmp(item_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(item, two[0].c_str(), &temp_value)); + } + else if (strcmp(rev_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(attachment, two[0].c_str(), &temp_value)); + } + else if (strcmp(form_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(forms[0], two[0].c_str(), &temp_value)); + } + else if (classificationObject != NULL && strcmp(one[0].c_str(), "classField") == 0) { + ICS_ask_attribute_value(classificationObject, two[0].c_str(), &temp_value); + } + if (temp_value != NULL) { + sql.append(temp_value); + + } + sql.append("',"); + } + } + WriteLog("8\n"); + sql.erase(sql.size() - 1, 1); + sql.append(" WHERE \"ItemID\" = '"); + sql.append(item_id); + sql.append("'"); + } + else if (strcmp("insert", deal_type) == 0) { + sql.append("INSERT INTO ["); + sql.append(form_name); + sql.append("]("); + //ֵֶ + WriteLog("9\n"); + for (int i = 0; i < valueNum; i++) + { + vector one; + Split(pre_values[i], "=", one); + sql.append("["); + sql.append(one[1]); + sql.append("]"); + if (i < valueNum - 1) { + sql.append(","); + } + } + WriteLog("10\n"); + sql.append(") VALUES ("); + //ֵֶεֵ + for (int i = 0; i < valueNum; i++) + { + WriteLog("11\n"); + vector one; + WriteLog("11 1\n"); + vector two; + WriteLog("11 2\n"); + Split(pre_values[i], ".", one); + WriteLog("11 3\n"); + Split(one[1], "=", two); + WriteLog("11 4\n"); + char* temp_value = NULL; + WriteLog("11 5\n"); + if (strcmp("ItemID", two[1].c_str()) == 0) { + sql.append("'"); + if (strcmp(item_type, one[0].c_str()) == 0) { + WriteLog("11 6\n"); + ITKCALL(AOM_ask_value_string(item, two[0].c_str(), &temp_value)); + } + else if (strcmp(rev_type, one[0].c_str()) == 0) { + WriteLog("11 7\n"); + ITKCALL(AOM_ask_value_string(attachment, two[0].c_str(), &temp_value)); + } + else if (strcmp(form_type, one[0].c_str()) == 0) { + WriteLog("11 8\n"); + ITKCALL(AOM_ask_value_string(forms[0], two[0].c_str(), &temp_value)); + } + else if (classificationObject != NULL && strcmp(one[0].c_str(), "classField") == 0) { + WriteLog("11 9\n"); + ICS_ask_attribute_value(classificationObject, two[0].c_str(), &temp_value); + WriteLog("11 10\n"); + } + WriteLog("11 11\n"); + if (temp_value != NULL) { + sql.append(temp_value); + WriteLog("11 12\n"); + + WriteLog("11 13\n"); + } + sql.append("',"); + } + else { + WriteLog("12\n"); + sql.append("'"); + if (strcmp(item_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(item, two[0].c_str(), &temp_value)); + } + else if (strcmp(rev_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(attachment, two[0].c_str(), &temp_value)); + } + else if (strcmp(form_type, one[0].c_str()) == 0) { + ITKCALL(AOM_ask_value_string(forms[0], two[0].c_str(), &temp_value)); + } + else if (classificationObject != NULL && strcmp(one[0].c_str(), "classField") == 0) { + ICS_ask_attribute_value(classificationObject, two[0].c_str(), &temp_value); + } + WriteLog("12 11\n"); + if (temp_value != NULL) { + sql.append(temp_value); + WriteLog("12 12\n"); + + WriteLog("12 13\n"); + } + sql.append("',"); + } + } + WriteLog("13\n"); + sql.erase(sql.size() - 1, 1); + sql.append(")"); + } + return sql; +} + +/******************************************************************* +* +*ǩϢд뵽мļ +* +*@param file_content ǩϢ +*@param item_id id +*@param file_name ļ +* +*******************************************************************/ +int Supor_create_signinfo_file(char* file_content, char* item_id, char** file_name) +{ + time_t now; + struct tm* p; + FILE* filePtr = NULL; + char temp_dir[MAX_PATH_LENGTH]; + char local_path[MAX_PATH] = ""; + char date_string[MAX_PATH_LENGTH]; + memset(temp_dir, 0, sizeof(temp_dir)); + memset(local_path, 0, sizeof(local_path)); + sprintf(temp_dir, "%s", getenv("TEMP")); + printf("\n file dir: %s\n", temp_dir); + time(&now); + p = localtime(&now); + if (chdir(temp_dir) != ITK_ok) + { + memset(temp_dir, 0, sizeof(temp_dir)); + sprintf(temp_dir, "%s", getenv("TC_LOG")); + printf("\n TC_USER_LOG_DIR invalide, log file dir: %s\n", temp_dir); + if (chdir(temp_dir) != ITK_ok) + { + printf("!*ERROR*!: Failed to change dir to TC_USER_LOG_DIR\n"); + + } + } + memset(date_string, 0, sizeof(date_string)); + if (item_id != NULL) { + sprintf(date_string, "%s_%4d%02d%02d%02d%02d%02d.dat", item_id, 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + } + else + { + sprintf(date_string, "%4d%02d%02d%02d%02d%02d.dat", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + } + printf("file name: %s\n", date_string); + filePtr = fopen(date_string, "w"); + printf("create the temp dat file success!\n"); + *file_name = (char*)MEM_alloc(sizeof(char) * 512); + sprintf(local_path, "%s\\%s", temp_dir, date_string); + strcpy((*file_name), local_path); + fprintf(filePtr, "%s", file_content); + //fwrite(file_content, sizeof(char), strlen(file_content), filePtr); + fclose(filePtr); + + return ITK_ok; +} \ No newline at end of file diff --git a/CONNOR_ITK/connor_itk_util.h b/CONNOR_ITK/connor_itk_util.h new file mode 100644 index 0000000..14829e2 --- /dev/null +++ b/CONNOR_ITK/connor_itk_util.h @@ -0,0 +1,71 @@ +#pragma once +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +//#include +//#include +//#include +//#include + +//#include +//#include +#ifdef __cplusplus +extern "C" { +#endif + +#define DOFREE(obj) \ +{ \ + if(obj) \ + { \ + MEM_free(obj); \ + obj = NULL; \ + } \ +} +void ECHO(char* format, ...); +void CreateLogFile(char* FunctionName, char** fullname); +void WriteLog(const char* format, ...); +void CloseLog(void); +string getUUid(); +void current_time(date_t* date_tag); +char* getTime(); +char* GbkToUtf8(const char* src_str); +char* Utf8ToGbk(const char* src_str); +void starTime(); +logical checkIsItemRevision(tag_t objtag); +int checkIsInType(tag_t objtag, string parentType); +int getPrefStrings(const char* preference, vector& pref_vec); +bool isTypeOf(tag_t objtag, const char* type_name); +void Split(string strArg, string spliter, vector& ans); +string dealPre(tag_t attachment, char* item_id, char* form_name, char* deal_type, tag_t classificationObject,char* typePref); +int Supor_create_signinfo_file(char* file_content, char* item_id, char** file_name); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/CONNOR_ITK/epm_handler_common.h b/CONNOR_ITK/epm_handler_common.h new file mode 100644 index 0000000..7dc8c40 --- /dev/null +++ b/CONNOR_ITK/epm_handler_common.h @@ -0,0 +1,98 @@ + + + +#ifndef EPM_HANDLER_COMMON +#define EPM_HANDLER_COMMON + +#include "tinyxml.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocilib.h" +#include "connor_itk_util.h" +#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")rename("BOF","adoBOF") + +#pragma comment(lib, "WinInet.lib") + +using namespace std; + +#ifdef __cplusplus +extern "C" { +#endif + +#define DOFREE(obj); + extern "C" int POM_AM__set_application_bypass(logical bypass); + bool create_adhoc_signoff(tag_t current_task, vector userID); + const char * inputFileToFtp(char * filePath); + char * getLineCode(char * lineCode); + //void removeChar(char* str, char c); + char* U2G(const char* utf8); + const char* newGUID(); + string replace_all_distinct(char* strC, char* old_valueC, char* new_valueC); + void split(char *src, const char *separator, char **dest, int *num); + int gbk_strlen(const char* str); + void stringToLenth(int value, int num, char ** result); + bool count(vector values, char * value); + void BOMSendToWeixin(char * userId, tag_t rootTask_tag, string message); + void itemSendToWeixin(char * userId, tag_t rootTask_tag, string message); + void TCFindItem(char * queryName, int n_entries, char ** qry_entries, char ** qry_values, int * n_found, tag_t ** dba_mbrs); + void TCGetPropertyValue(tag_t item, char * type, char * propertyName, char ** propertyValue); + int ORIGIN_set_bypass(void *returnValue); + int ORIGIN_close_bypass(void *returnValue); + int RB_SendErpItem(EPM_action_message_t msg); + int RB_SendErpBom(EPM_action_message_t msg); + int RB_CheckForCompletion(EPM_action_message_t msg); + int RB_PLM2LIMS_JCSY(EPM_action_message_t msg); + int RB_testquery_ID(EPM_action_message_t msg); + bool startsWith(const char* str, char first, char second); + char* removeChar(char* str, char charToRemove); + char* removeSpaces(char* str); + void removeFirstFourChars(char* str); + char* getFirstStr(const char* str, int index); + void getClassValue(char* value, int id, char** disValue); + int RB_SendErpItem_New(EPM_action_message_t msg); + int RB_SendErpBom_New(EPM_action_message_t msg); + int RB_Send_MDM_GYLX_New(EPM_action_message_t msg); + int RB_SendGX_New(EPM_action_message_t msg); + int RB_SendErpItem_New_Rule(EPM_rule_message_t msg); + int RB_SendErpBom_New_Rule(EPM_rule_message_t msg); + int RB_SendErpItem_New_Rule_Release(EPM_rule_message_t msg); + int RB_SendErpBom_New_Rule_Release(EPM_rule_message_t msg); + int RB_BOM_TO_ERP(EPM_action_message_t msg); +#ifdef __cplusplus +} +#endif + +#endif + + +/** +* @} +*/ \ No newline at end of file diff --git a/CONNOR_ITK/epm_register_handler.cxx b/CONNOR_ITK/epm_register_handler.cxx new file mode 100644 index 0000000..66d4c59 --- /dev/null +++ b/CONNOR_ITK/epm_register_handler.cxx @@ -0,0 +1,247 @@ +#include +#include + + +#include +#include +#include +#include +#include +/** +* @headerfile user's header files +*/ +#include "epm_register_handler.h" +#include "epm_handler_common.h" +#include "RB_AutoSignServer.h" + +using namespace std; + +// Method and Workflow Handler +extern DLLAPI int CUST_init_module(int *decision, va_list args) +{ + int ifail = ITK_ok; + + + //齻Ϲϵ + ifail = EPM_register_action_handler("RB_CheckForCompletion", "RB_CheckForCompletion", + (EPM_action_handler_t)RB_CheckForCompletion); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_CheckForCompletion completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_CheckForCompletion failed %d!\n", ifail); + } + + + //·SAP + ifail = EPM_register_action_handler("RB_SendSapItem", "RB_SendSapItem", + (EPM_action_handler_t)RB_SendErpItem); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_SendSapItem completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_SendSapItem failed %d!\n", ifail); + } + //·SAP-°汾 + ifail = EPM_register_action_handler("RB_SendErpItem_New", "RB_SendErpItem_New", + (EPM_action_handler_t)RB_SendErpItem_New); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_SendErpItem_New completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_SendErpItem_New failed %d!\n", ifail); + } + + //·SAP-°汾 Rule + ifail = EPM_register_rule_handler("RB_SendErpItem_New_Rule", "RB_SendErpItem_New_Rule", + (EPM_rule_handler_t)RB_SendErpItem_New_Rule); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering rule handler RB_SendErpItem_New_Rule completed!\n"); + } + else + { + fprintf(stdout, "Registering rule handler RB_SendErpItem_New_Rule failed %d!\n", ifail); + } + + + + //·SAP-°汾 Rule Release + ifail = EPM_register_rule_handler("RB_SendErpItem_New_Rule_Release", "RB_SendErpItem_New_Rule_Release", + (EPM_rule_handler_t)RB_SendErpItem_New_Rule_Release); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering rule handler RB_SendErpItem_New_Rule_Release completed!\n"); + } + else + { + fprintf(stdout, "Registering rule handler RB_SendErpItem_New_Rule_Release failed %d!\n", ifail); + } + + + + + //BOM·SAP + ifail = EPM_register_action_handler("RB_SendSapBom", "RB_SendSapBom", + (EPM_action_handler_t)RB_SendErpBom); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_SendSapBom completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_SendSapBom failed %d!\n", ifail); + } + //BOM·SAP--°汾 + ifail = EPM_register_action_handler("RB_SendErpBom_New", "RB_SendErpBom_New", + (EPM_action_handler_t)RB_SendErpBom_New); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_SendErpBom_New completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_SendErpBom_New failed %d!\n", ifail); + } + + //BOM·SAP--°汾rule + ifail = EPM_register_rule_handler("RB_SendErpBom_New_Rule", "RB_SendErpBom_New_Rule", + (EPM_rule_handler_t)RB_SendErpBom_New_Rule); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering rule handler RB_SendErpBom_New_Rule completed!\n"); + } + else + { + fprintf(stdout, "Registering rule handler RB_SendErpBom_New_Rule failed %d!\n", ifail); + } + + + //BOM·SAP--°汾rule Release + ifail = EPM_register_rule_handler("RB_SendErpBom_New_Rule_Release", "RB_SendErpBom_New_Rule_Release", + (EPM_rule_handler_t)RB_SendErpBom_New_Rule_Release); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering rule handler RB_SendErpBom_New_Rule_Release completed!\n"); + } + else + { + fprintf(stdout, "Registering rule handler RB_SendErpBom_New_Rule_Release failed %d!\n", ifail); + } + + //·SAP--°汾 + ifail = EPM_register_action_handler("RB_SendGX_New", "RB_SendGX_New", + (EPM_action_handler_t)RB_SendGX_New); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_SendGX_New completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_SendGX_New failed %d!\n", ifail); + } + //··SAP--°汾 + ifail = EPM_register_action_handler("RB_Send_MDM_GYLX_New", "RB_Send_MDM_GYLX_New", + (EPM_action_handler_t)RB_Send_MDM_GYLX_New); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_Send_MDM_GYLX_New completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_Send_MDM_GYLX_New failed %d!\n", ifail); + } + //TCίеϢLIMS + ifail = EPM_register_action_handler("RB_PLM2LIMS_JCSY", "RB_PLM2LIMS_JCSY", + (EPM_action_handler_t)RB_PLM2LIMS_JCSY); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_PLM2LIMS_JCSY completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_PLM2LIMS_JCSY failed %d!\n", ifail); + } + + //TCίеϢLIMS + ifail = EPM_register_action_handler("RB_testquery_ID", "RB_testquery_ID", + (EPM_action_handler_t)RB_testquery_ID); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_testquery_ID completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_testquery_ID failed %d!\n", ifail); + } + + ifail = EPM_register_action_handler("RB_BOM_TO_ERP", "RB_BOM_TO_ERP", + (EPM_action_handler_t)RB_BOM_TO_ERP); + if (ifail == ITK_ok) + { + fprintf(stdout, "Registering action handler RB_BOM_TO_ERP completed!\n"); + } + else + { + fprintf(stdout, "Registering action handler RB_BOM_TO_ERP failed %d!\n", ifail); + } + + return ifail; +} +// +////register service method +extern DLLAPI int USERSERVICE_custom_register_methods() +{ + int + status = ITK_ok, + numberOfArguments = 0, + returnValueType = USERARG_STRING_TYPE, + *argumentList = NULL; + USER_function_t functionPtr; + + METHOD_id_t mth_tag; + + //=========================================== + + /*METHOD_find_method("ScheduleTask", ITEM_create_msg, &mth_tag); + if (mth_tag.id) + { + status = METHOD_add_action(mth_tag, METHOD_post_action_type, (METHOD_function_t)ML_Test, NULL); + if (status == ITK_ok) + { + printf("register wx3_tzcpxh_check successfully\n "); + } + else + { + printf("register wx3_tzcpxh_check failed\n "); + } + + }*/ + + //=========================================== + //ȡ̽ڵԶ + numberOfArguments = 2; + functionPtr = RB_AutoSignServer; + argumentList = (int*)MEM_alloc(numberOfArguments * sizeof(int)); + argumentList[0] = USERARG_STRING_TYPE; //Ҫִеsignoffpuid + argumentList[1] = USERARG_STRING_TYPE; //ĽڵPUID + returnValueType = USERARG_STRING_TYPE; //ֵ + ITKCALL(status = USERSERVICE_register_method("RB_AutoSignServer", functionPtr, numberOfArguments, argumentList, returnValueType)); + MEM_free(argumentList); + if (status == ITK_ok) + { + fprintf(stdout, "Registering userservice RB_AutoSignServer successful !\n"); + } + else { + fprintf(stdout, "Registering userservice RB_AutoSignServer failed %d\n", status); + } + return(status); +} + + diff --git a/CONNOR_ITK/epm_register_handler.h b/CONNOR_ITK/epm_register_handler.h new file mode 100644 index 0000000..264ce72 --- /dev/null +++ b/CONNOR_ITK/epm_register_handler.h @@ -0,0 +1,21 @@ + + +#ifndef EPM_REGISTER_HANDLER_CUSTOM +#define EPM_REGISTER_HANDLER_CUSTOM + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + extern DLLAPI int CUST_init_module(int *, va_list); + extern DLLAPI int USERSERVICE_custom_register_methods(); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/CONNOR_ITK/mylog.h b/CONNOR_ITK/mylog.h new file mode 100644 index 0000000..c11a3b6 --- /dev/null +++ b/CONNOR_ITK/mylog.h @@ -0,0 +1,95 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +using namespace std; + +static std::mutex _mtx; + +class Log +{ +public: + Log(); + ~Log(); + + static void info(std::string log) + { + string type = "INFO"; + write(log, type); + } + + static void debug(std::string log) + { + string type = "DEBUG"; + write(log, type); + } + + static void warning(std::string log) + { + string type = "WARNING"; + write(log, type); + } + + static void error(std::string log) + { + string type = "ERROR"; + write(log, type); + } + + static void critical(std::string log) + { + string type = "CRITICAL"; + write(log, type); + } + + static std::string getTimestamp() + { + time_t timep; + time(&timep); + char tmp[64]; + struct tm nowTime; + localtime_s(&nowTime, &timep); + strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H:%M:%S", &nowTime); + return std::string(tmp); + } + + static void string_replace(string& s1, const string& s2, const string& s3) + { + string::size_type pos = 0; + string::size_type a = s2.size(); + string::size_type b = s3.size(); + + while ((pos = s1.find(s2, pos)) != string::npos) + { + s1.replace(pos, a, s3); + pos += b; + } + } + + + static void write(std::string log, std::string type) + { + string filePath = "C:/test.log"; //־ļ· + std::ofstream ofs; + + _mtx.lock(); + + ofs.open(filePath, std::ofstream::app); + + ofs << getTimestamp().c_str() << "-"; + ofs << "[" << type.c_str() << "]-"; + + ofs.write(log.c_str(), log.size()); + ofs << std::endl; + ofs.close(); + + _mtx.unlock(); + } +}; + + + diff --git a/CONNOR_ITK/occidml - 副本.cpp b/CONNOR_ITK/occidml - 副本.cpp new file mode 100644 index 0000000..82d8dd4 --- /dev/null +++ b/CONNOR_ITK/occidml - 副本.cpp @@ -0,0 +1,581 @@ + + +#include +#include +using namespace oracle::occi; +using namespace std; + +class occidml +{ + private: + + + public: + Environment* env; + oracle::occi::Connection* conn; + Statement* stmt; + occidml (string user, string passwd, string db) + { +#ifdef _WIN32 + _putenv("NLS_LANG=AMERICAN_AMERICA.ZHS16GBK"); +#else + setenv("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK", 1); +#endif + printf("0-\n"); + env = Environment::createEnvironment (Environment::DEFAULT); + printf("1-\n"); + conn = env->createConnection (user, passwd, db); + printf("2-\n"); + } + + ~occidml () + { + printf("3-\n"); + env->terminateConnection (conn); + printf("4-\n"); + Environment::terminateEnvironment (env); + printf("5-\n"); + } + + + + string safeGetString(ResultSet* rset, int colIndex) { + try { + if (rset->isNull(colIndex)) { + return "NULL"; + } + + Bytes bytes = rset->getBytes(colIndex); + if (bytes.length() <= 0) { + return ""; + } + + // ֽ + unsigned char* buf = new unsigned char[bytes.length()]; + bytes.getBytes(buf, bytes.length()); + + string result(reinterpret_cast(buf), bytes.length()); + delete[] buf; + + return result; + } + catch (...) { + return "ERROR"; + } + } + + /** + * Insertion of a row with dynamic binding, PreparedStatement functionality. + */ + void insertBind (int c1, string c2) + { + string sqlStmt = "INSERT INTO author_tab VALUES (:x, :y)"; + stmt=conn->createStatement (sqlStmt); + try{ + stmt->setInt (1, c1); + stmt->setString (2, c2); + stmt->executeUpdate (); + cout << "insert - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for insertBind"<terminateStatement (stmt); + } + + /** + * Inserting a row into the table. + */ + void insertRow () + { + string sqlStmt = "INSERT INTO author_tab VALUES (111, 'ASHOK')"; + stmt = conn->createStatement (sqlStmt); + try{ + stmt->executeUpdate (); + cout << "insert - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for insertRow"<terminateStatement (stmt); + } + + /** + * updating a row + */ + void updateRow (int c1, string c2) + { + string sqlStmt = + "UPDATE author_tab SET author_name = :x WHERE author_id = :y"; + stmt = conn->createStatement (sqlStmt); + try{ + stmt->setString (1, c2); + stmt->setInt (2, c1); + stmt->executeUpdate (); + cout << "update - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for updateRow"<terminateStatement (stmt); + } + + + /** + * deletion of a row + */ + void deleteRow (int c1, string c2) + { + string sqlStmt = + "DELETE FROM author_tab WHERE author_id= :x AND author_name = :y"; + stmt = conn->createStatement (sqlStmt); + try{ + stmt->setInt (1, c1); + stmt->setString (2, c2); + stmt->executeUpdate (); + cout << "delete - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for deleteRow"<terminateStatement (stmt); + } + + /** + * displaying all the rows in the table + */ + void displayAllRows () + { + string sqlStmt = "SELECT author_id, author_name FROM author_tab \ + order by author_id"; + stmt = conn->createStatement (sqlStmt); + ResultSet *rset = stmt->executeQuery (); + try{ + while (rset->next ()) + { + cout << "author_id: " << rset->getInt (1) << " author_name: " + << rset->getString (2) << endl; + } + }catch(SQLException ex) + { + cout<<"Exception thrown for displayAllRows"<closeResultSet (rset); + conn->terminateStatement (stmt); + } + + /** + * Inserting a row into elements table. + * Demonstrating the usage of BFloat and BDouble datatypes + */ + void insertElement (string elm_name, float mvol=0.0, double awt=0.0) + { + BFloat mol_vol; + BDouble at_wt; + + if (!(mvol)) + mol_vol.isNull = TRUE; + else + mol_vol.value = mvol; + + if (!(awt)) + at_wt.isNull = TRUE; + else + at_wt.value = awt; + + string sqlStmt = "INSERT INTO elements VALUES (:v1, :v2, :v3)"; + stmt = conn->createStatement (sqlStmt); + + try{ + stmt->setString(1, elm_name); + stmt->setBFloat(2, mol_vol); + stmt->setBDouble(3, at_wt); + stmt->executeUpdate (); + cout << "insertElement - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for insertElement"<terminateStatement (stmt); + } + + /** + * displaying rows from element table + */ + void displayElements () + { + string sqlStmt = + "SELECT element_name, molar_volume, atomic_weight FROM elements \ + order by element_name"; + stmt = conn->createStatement (sqlStmt); + ResultSet *rset = stmt->executeQuery (); + try{ + cout.precision(7); + while (rset->next ()) + { + string elem_name = rset->getString(1); + BFloat mol_vol = rset->getBFloat(2); + BDouble at_wt = rset->getBDouble(3); + + cout << "Element Name: " << elem_name << endl; + + if ( mol_vol.isNull ) + cout << "Molar Volume is NULL" << endl; + else + cout << "Molar Volume: " << mol_vol.value << " cm3 mol-1" << endl; + + if ( at_wt.isNull ) + cout << "Atomic Weight is NULL" << endl; + else + cout << "Atomic Weight: " << at_wt.value << " g/mole" << endl; + } + }catch(SQLException ex) + { + cout<<"Exception thrown for displayElements"<closeResultSet (rset); + conn->terminateStatement (stmt); + } + + + /** + * װ OCCI executeQuery Ϊ C ӿ + * + * @param conn OCCI ݿ + * @param sql SQL ѯ + * @param outputColumn ָͨ뷵أ + * @param outputValueCount + * @param outputValue ά char[row][col]ͷ + * @return 0=ɹ, -1=ʧ + */ + + + + +int executeQuery( + oracle::occi::Connection* conn, + const char* sql, + int* outputColumn, + int* outputValueCount, + char**** outputValue) +{ + printf("DEBUG: Entering executeQuery function\n"); + fflush(stdout); + + // ʼ + *outputColumn = 0; + printf("DEBUG: Initialized outputColumn = 0\n"); + fflush(stdout); + + *outputValueCount = 0; + printf("DEBUG: Initialized outputValueCount = 0\n"); + fflush(stdout); + + *outputValue = nullptr; + printf("DEBUG: Set outputValue to nullptr\n"); + fflush(stdout); + + Statement* stmt = nullptr; + ResultSet* rset = nullptr; + vector> resultData; + + try { + printf("DEBUG: Entering try block\n"); + fflush(stdout); + + printf("DEBUG: sql====%s\n", sql); + fflush(stdout); + // + stmt = conn->createStatement(sql); + printf("DEBUG: Created statement from connection\n"); + fflush(stdout); + + // ִвѯ + rset = stmt->executeQuery(); + printf("DEBUG: Executed query and got ResultSet\n"); + fflush(stdout); + + // ؼ޸ȵ next() ٻȡԪݣֹ + bool hasData = rset->next(); + printf("DEBUG: First rset->next() called for initialization, hasData = %s\n", hasData ? "true" : "false"); + fflush(stdout); + + // ȡԪݣ next() ֮òŰȫ + auto metaData = rset->getColumnListMetaData(); + unsigned int numCols = 0; + if (!metaData.empty()) { + numCols = static_cast(metaData.size()); + printf("DEBUG: Got number of columns = %u\n", numCols); + fflush(stdout); + } + else { + printf("ERROR: Metadata is empty after next(), unable to get column count.\n"); + fflush(stdout); + stmt->closeResultSet(rset); + conn->terminateStatement(stmt); + return -1; + } + fflush(stdout); + + // ݣһ + if (hasData) { + vector firstRow; + for (unsigned int i = 1; i <= numCols; ++i) { + printf("DEBUG: Processing column %u of first row\n", i); + fflush(stdout); + try { + //string val = rset->getString(i); + //printf("DEBUG: Retrieved value for column %u: '%s'\n", i, val.c_str()); + //fflush(stdout); + //firstRow.push_back(val); + + + string val = safeGetString(rset, i); + printf("DEBUG: Retrieved value for column %u: '%s'\n", i, val.c_str()); + firstRow.push_back(val); + + + + printf("1111111111111111111111111\n"); + } + catch (SQLException&) { + printf("DEBUG: Exception getting column %u, using 'NULL'\n", i); + fflush(stdout); + firstRow.push_back("NULL"); + } + catch (exception& e) { + printf("exception=========%u\n", i); + printf("Exception caught on column %u: %s\n", i, e.what()); + + fflush(stdout); + } + } + printf("22222222222222222222\n"); + resultData.push_back(firstRow); + printf("DEBUG: First row saved to resultData\n"); + fflush(stdout); + } + + // ȡʣ + unsigned int rowCount = static_cast(resultData.size()); + printf("DEBUG: Starting to fetch remaining rows\n"); + fflush(stdout); + + while (rset->next()) { + printf("DEBUG: Fetching next row\n"); + fflush(stdout); + + vector row; + for (unsigned int i = 1; i <= numCols; ++i) { + try { + string val = safeGetString(rset,i); + row.push_back(val); + printf("DEBUG: Retrieved value for row %u, col %u: '%s'\n", rowCount, i, val.c_str()); + fflush(stdout); + } + catch (SQLException&) { + row.push_back("NULL"); + printf("DEBUG: NULL value at row %u, col %u\n", rowCount, i); + fflush(stdout); + } + } + resultData.push_back(row); + ++rowCount; + printf("DEBUG: Completed row %u\n", rowCount); + fflush(stdout); + } + + printf("DEBUG: Finished fetching all rows, total count = %u\n", rowCount); + fflush(stdout); + + // + *outputColumn = static_cast(numCols); + *outputValueCount = static_cast(rowCount); + printf("DEBUG: Set outputColumn = %d, outputValueCount = %d\n", *outputColumn, *outputValueCount); + fflush(stdout); + + // ڴ棺char*** -> char**[] -> char*[] -> char[] + char*** rows = nullptr; + if (rowCount > 0) { + rows = new char** [rowCount]; // ÿһ char** + printf("DEBUG: Allocated %u row pointers\n", rowCount); + fflush(stdout); + + for (unsigned int i = 0; i < rowCount; ++i) { + char** cols = new char* [numCols]; + printf("DEBUG: Allocated %u column pointers for row %u\n", numCols, i); + fflush(stdout); + + for (unsigned int j = 0; j < numCols; ++j) { + const string& s = resultData[i][j]; + cols[j] = new char[s.length() + 1]; + strcpy(cols[j], s.c_str()); + printf("DEBUG: Copied '%s' to outputValue[%u][%u]\n", s.c_str(), i, j); + fflush(stdout); + } + rows[i] = cols; + } + } + else { + rows = nullptr; // ս + } + + *outputValue = rows; + printf("DEBUG: Assigned result to *outputValue\n"); + fflush(stdout); + + // OCCI Դ + stmt->closeResultSet(rset); + printf("DEBUG: Closed ResultSet\n"); + fflush(stdout); + + conn->terminateStatement(stmt); + printf("DEBUG: Terminated Statement\n"); + fflush(stdout); + + printf("DEBUG: Query executed successfully, returning 0\n"); + fflush(stdout); + + return 0; // ɹ + } + catch (SQLException& e) { + printf("DEBUG: SQLException caught\n"); + fflush(stdout); + cerr << "SQL Error: " << e.getMessage() << endl; + cerr << "SQL: " << sql << endl; + + // Դ + if (rset && stmt) { + try { stmt->closeResultSet(rset); } + catch (...) {} + } + if (stmt) { + try { conn->terminateStatement(stmt); } + catch (...) {} + } + + printf("DEBUG: Returning -1 due to SQL error\n"); + fflush(stdout); + return -1; + } + catch (bad_alloc& e) { + printf("DEBUG: bad_alloc exception caught: %s\n", e.what()); + fflush(stdout); + cerr << "Memory allocation failed!" << endl; + + // Դ + if (rset && stmt) { + try { stmt->closeResultSet(rset); } + catch (...) {} + } + if (stmt) { + try { conn->terminateStatement(stmt); } + catch (...) {} + } + + printf("DEBUG: Returning -2 due to memory allocation failure\n"); + fflush(stdout); + return -2; + } + catch (...) { + printf("DEBUG: Unknown exception caught\n"); + fflush(stdout); + + if (rset && stmt) { + try { stmt->closeResultSet(rset); } + catch (...) {} + } + if (stmt) { + try { conn->terminateStatement(stmt); } + catch (...) {} + } + + printf("DEBUG: Returning -1 due to unknown error\n"); + fflush(stdout); + return -1; + } +} + + + + + + + + + +}; // end of class occidml + + +//int main (void) +//{ +// string user = "scott"; +// string passwd = "tiger"; +// string db = ""; +// try{ +// cout << "occidml - Exhibiting simple insert, delete & update operations" +// << endl; +// occidml *demo = new occidml (user, passwd, db); +// cout << "Displaying all records before any operation" << endl; +// demo->displayAllRows (); +// +// cout << "Inserting a record into the table author_tab " +// << endl; +// demo->insertRow (); +// +// cout << "Displaying the records after insert " << endl; +// demo->displayAllRows (); +// +// cout << "Inserting a records into the table author_tab using dynamic bind" +// << endl; +// demo->insertBind (222, "ANAND"); +// +// cout << "Displaying the records after insert using dynamic bind" << endl; +// demo->displayAllRows (); +// +// cout << "deleting a row with author_id as 222 from author_tab table" << endl; +// demo->deleteRow (222, "ANAND"); +// +// cout << "updating a row with author_id as 444 from author_tab table" << endl; +// demo->updateRow (444, "ADAM"); +// +// cout << "displaying all rows after all the operations" << endl; +// demo->displayAllRows (); +// +// cout << "inserting radio active element properties" << endl; +// demo->insertElement ("Uranium", 12.572, 238.0289 ); +// demo->insertElement ("Plutonium", 12.12, 244.0642 ); +// demo->insertElement ("Curium", 18.17, 247.0703 ); +// demo->insertElement ("Thorium"); +// demo->insertElement ("Radium", 41.337, 226.0254); +// +// cout << "displaying all radio active element properties" << endl; +// demo->displayElements (); +// +// delete (demo); +// } +// catch (SQLException ex){ +// cout << ex.getMessage() << endl; +// } +// cout << "occidml - done" << endl; +//} diff --git a/CONNOR_ITK/occidml.cpp b/CONNOR_ITK/occidml.cpp new file mode 100644 index 0000000..82d8dd4 --- /dev/null +++ b/CONNOR_ITK/occidml.cpp @@ -0,0 +1,581 @@ + + +#include +#include +using namespace oracle::occi; +using namespace std; + +class occidml +{ + private: + + + public: + Environment* env; + oracle::occi::Connection* conn; + Statement* stmt; + occidml (string user, string passwd, string db) + { +#ifdef _WIN32 + _putenv("NLS_LANG=AMERICAN_AMERICA.ZHS16GBK"); +#else + setenv("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK", 1); +#endif + printf("0-\n"); + env = Environment::createEnvironment (Environment::DEFAULT); + printf("1-\n"); + conn = env->createConnection (user, passwd, db); + printf("2-\n"); + } + + ~occidml () + { + printf("3-\n"); + env->terminateConnection (conn); + printf("4-\n"); + Environment::terminateEnvironment (env); + printf("5-\n"); + } + + + + string safeGetString(ResultSet* rset, int colIndex) { + try { + if (rset->isNull(colIndex)) { + return "NULL"; + } + + Bytes bytes = rset->getBytes(colIndex); + if (bytes.length() <= 0) { + return ""; + } + + // ֽ + unsigned char* buf = new unsigned char[bytes.length()]; + bytes.getBytes(buf, bytes.length()); + + string result(reinterpret_cast(buf), bytes.length()); + delete[] buf; + + return result; + } + catch (...) { + return "ERROR"; + } + } + + /** + * Insertion of a row with dynamic binding, PreparedStatement functionality. + */ + void insertBind (int c1, string c2) + { + string sqlStmt = "INSERT INTO author_tab VALUES (:x, :y)"; + stmt=conn->createStatement (sqlStmt); + try{ + stmt->setInt (1, c1); + stmt->setString (2, c2); + stmt->executeUpdate (); + cout << "insert - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for insertBind"<terminateStatement (stmt); + } + + /** + * Inserting a row into the table. + */ + void insertRow () + { + string sqlStmt = "INSERT INTO author_tab VALUES (111, 'ASHOK')"; + stmt = conn->createStatement (sqlStmt); + try{ + stmt->executeUpdate (); + cout << "insert - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for insertRow"<terminateStatement (stmt); + } + + /** + * updating a row + */ + void updateRow (int c1, string c2) + { + string sqlStmt = + "UPDATE author_tab SET author_name = :x WHERE author_id = :y"; + stmt = conn->createStatement (sqlStmt); + try{ + stmt->setString (1, c2); + stmt->setInt (2, c1); + stmt->executeUpdate (); + cout << "update - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for updateRow"<terminateStatement (stmt); + } + + + /** + * deletion of a row + */ + void deleteRow (int c1, string c2) + { + string sqlStmt = + "DELETE FROM author_tab WHERE author_id= :x AND author_name = :y"; + stmt = conn->createStatement (sqlStmt); + try{ + stmt->setInt (1, c1); + stmt->setString (2, c2); + stmt->executeUpdate (); + cout << "delete - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for deleteRow"<terminateStatement (stmt); + } + + /** + * displaying all the rows in the table + */ + void displayAllRows () + { + string sqlStmt = "SELECT author_id, author_name FROM author_tab \ + order by author_id"; + stmt = conn->createStatement (sqlStmt); + ResultSet *rset = stmt->executeQuery (); + try{ + while (rset->next ()) + { + cout << "author_id: " << rset->getInt (1) << " author_name: " + << rset->getString (2) << endl; + } + }catch(SQLException ex) + { + cout<<"Exception thrown for displayAllRows"<closeResultSet (rset); + conn->terminateStatement (stmt); + } + + /** + * Inserting a row into elements table. + * Demonstrating the usage of BFloat and BDouble datatypes + */ + void insertElement (string elm_name, float mvol=0.0, double awt=0.0) + { + BFloat mol_vol; + BDouble at_wt; + + if (!(mvol)) + mol_vol.isNull = TRUE; + else + mol_vol.value = mvol; + + if (!(awt)) + at_wt.isNull = TRUE; + else + at_wt.value = awt; + + string sqlStmt = "INSERT INTO elements VALUES (:v1, :v2, :v3)"; + stmt = conn->createStatement (sqlStmt); + + try{ + stmt->setString(1, elm_name); + stmt->setBFloat(2, mol_vol); + stmt->setBDouble(3, at_wt); + stmt->executeUpdate (); + cout << "insertElement - Success" << endl; + }catch(SQLException ex) + { + cout<<"Exception thrown for insertElement"<terminateStatement (stmt); + } + + /** + * displaying rows from element table + */ + void displayElements () + { + string sqlStmt = + "SELECT element_name, molar_volume, atomic_weight FROM elements \ + order by element_name"; + stmt = conn->createStatement (sqlStmt); + ResultSet *rset = stmt->executeQuery (); + try{ + cout.precision(7); + while (rset->next ()) + { + string elem_name = rset->getString(1); + BFloat mol_vol = rset->getBFloat(2); + BDouble at_wt = rset->getBDouble(3); + + cout << "Element Name: " << elem_name << endl; + + if ( mol_vol.isNull ) + cout << "Molar Volume is NULL" << endl; + else + cout << "Molar Volume: " << mol_vol.value << " cm3 mol-1" << endl; + + if ( at_wt.isNull ) + cout << "Atomic Weight is NULL" << endl; + else + cout << "Atomic Weight: " << at_wt.value << " g/mole" << endl; + } + }catch(SQLException ex) + { + cout<<"Exception thrown for displayElements"<closeResultSet (rset); + conn->terminateStatement (stmt); + } + + + /** + * װ OCCI executeQuery Ϊ C ӿ + * + * @param conn OCCI ݿ + * @param sql SQL ѯ + * @param outputColumn ָͨ뷵أ + * @param outputValueCount + * @param outputValue ά char[row][col]ͷ + * @return 0=ɹ, -1=ʧ + */ + + + + +int executeQuery( + oracle::occi::Connection* conn, + const char* sql, + int* outputColumn, + int* outputValueCount, + char**** outputValue) +{ + printf("DEBUG: Entering executeQuery function\n"); + fflush(stdout); + + // ʼ + *outputColumn = 0; + printf("DEBUG: Initialized outputColumn = 0\n"); + fflush(stdout); + + *outputValueCount = 0; + printf("DEBUG: Initialized outputValueCount = 0\n"); + fflush(stdout); + + *outputValue = nullptr; + printf("DEBUG: Set outputValue to nullptr\n"); + fflush(stdout); + + Statement* stmt = nullptr; + ResultSet* rset = nullptr; + vector> resultData; + + try { + printf("DEBUG: Entering try block\n"); + fflush(stdout); + + printf("DEBUG: sql====%s\n", sql); + fflush(stdout); + // + stmt = conn->createStatement(sql); + printf("DEBUG: Created statement from connection\n"); + fflush(stdout); + + // ִвѯ + rset = stmt->executeQuery(); + printf("DEBUG: Executed query and got ResultSet\n"); + fflush(stdout); + + // ؼ޸ȵ next() ٻȡԪݣֹ + bool hasData = rset->next(); + printf("DEBUG: First rset->next() called for initialization, hasData = %s\n", hasData ? "true" : "false"); + fflush(stdout); + + // ȡԪݣ next() ֮òŰȫ + auto metaData = rset->getColumnListMetaData(); + unsigned int numCols = 0; + if (!metaData.empty()) { + numCols = static_cast(metaData.size()); + printf("DEBUG: Got number of columns = %u\n", numCols); + fflush(stdout); + } + else { + printf("ERROR: Metadata is empty after next(), unable to get column count.\n"); + fflush(stdout); + stmt->closeResultSet(rset); + conn->terminateStatement(stmt); + return -1; + } + fflush(stdout); + + // ݣһ + if (hasData) { + vector firstRow; + for (unsigned int i = 1; i <= numCols; ++i) { + printf("DEBUG: Processing column %u of first row\n", i); + fflush(stdout); + try { + //string val = rset->getString(i); + //printf("DEBUG: Retrieved value for column %u: '%s'\n", i, val.c_str()); + //fflush(stdout); + //firstRow.push_back(val); + + + string val = safeGetString(rset, i); + printf("DEBUG: Retrieved value for column %u: '%s'\n", i, val.c_str()); + firstRow.push_back(val); + + + + printf("1111111111111111111111111\n"); + } + catch (SQLException&) { + printf("DEBUG: Exception getting column %u, using 'NULL'\n", i); + fflush(stdout); + firstRow.push_back("NULL"); + } + catch (exception& e) { + printf("exception=========%u\n", i); + printf("Exception caught on column %u: %s\n", i, e.what()); + + fflush(stdout); + } + } + printf("22222222222222222222\n"); + resultData.push_back(firstRow); + printf("DEBUG: First row saved to resultData\n"); + fflush(stdout); + } + + // ȡʣ + unsigned int rowCount = static_cast(resultData.size()); + printf("DEBUG: Starting to fetch remaining rows\n"); + fflush(stdout); + + while (rset->next()) { + printf("DEBUG: Fetching next row\n"); + fflush(stdout); + + vector row; + for (unsigned int i = 1; i <= numCols; ++i) { + try { + string val = safeGetString(rset,i); + row.push_back(val); + printf("DEBUG: Retrieved value for row %u, col %u: '%s'\n", rowCount, i, val.c_str()); + fflush(stdout); + } + catch (SQLException&) { + row.push_back("NULL"); + printf("DEBUG: NULL value at row %u, col %u\n", rowCount, i); + fflush(stdout); + } + } + resultData.push_back(row); + ++rowCount; + printf("DEBUG: Completed row %u\n", rowCount); + fflush(stdout); + } + + printf("DEBUG: Finished fetching all rows, total count = %u\n", rowCount); + fflush(stdout); + + // + *outputColumn = static_cast(numCols); + *outputValueCount = static_cast(rowCount); + printf("DEBUG: Set outputColumn = %d, outputValueCount = %d\n", *outputColumn, *outputValueCount); + fflush(stdout); + + // ڴ棺char*** -> char**[] -> char*[] -> char[] + char*** rows = nullptr; + if (rowCount > 0) { + rows = new char** [rowCount]; // ÿһ char** + printf("DEBUG: Allocated %u row pointers\n", rowCount); + fflush(stdout); + + for (unsigned int i = 0; i < rowCount; ++i) { + char** cols = new char* [numCols]; + printf("DEBUG: Allocated %u column pointers for row %u\n", numCols, i); + fflush(stdout); + + for (unsigned int j = 0; j < numCols; ++j) { + const string& s = resultData[i][j]; + cols[j] = new char[s.length() + 1]; + strcpy(cols[j], s.c_str()); + printf("DEBUG: Copied '%s' to outputValue[%u][%u]\n", s.c_str(), i, j); + fflush(stdout); + } + rows[i] = cols; + } + } + else { + rows = nullptr; // ս + } + + *outputValue = rows; + printf("DEBUG: Assigned result to *outputValue\n"); + fflush(stdout); + + // OCCI Դ + stmt->closeResultSet(rset); + printf("DEBUG: Closed ResultSet\n"); + fflush(stdout); + + conn->terminateStatement(stmt); + printf("DEBUG: Terminated Statement\n"); + fflush(stdout); + + printf("DEBUG: Query executed successfully, returning 0\n"); + fflush(stdout); + + return 0; // ɹ + } + catch (SQLException& e) { + printf("DEBUG: SQLException caught\n"); + fflush(stdout); + cerr << "SQL Error: " << e.getMessage() << endl; + cerr << "SQL: " << sql << endl; + + // Դ + if (rset && stmt) { + try { stmt->closeResultSet(rset); } + catch (...) {} + } + if (stmt) { + try { conn->terminateStatement(stmt); } + catch (...) {} + } + + printf("DEBUG: Returning -1 due to SQL error\n"); + fflush(stdout); + return -1; + } + catch (bad_alloc& e) { + printf("DEBUG: bad_alloc exception caught: %s\n", e.what()); + fflush(stdout); + cerr << "Memory allocation failed!" << endl; + + // Դ + if (rset && stmt) { + try { stmt->closeResultSet(rset); } + catch (...) {} + } + if (stmt) { + try { conn->terminateStatement(stmt); } + catch (...) {} + } + + printf("DEBUG: Returning -2 due to memory allocation failure\n"); + fflush(stdout); + return -2; + } + catch (...) { + printf("DEBUG: Unknown exception caught\n"); + fflush(stdout); + + if (rset && stmt) { + try { stmt->closeResultSet(rset); } + catch (...) {} + } + if (stmt) { + try { conn->terminateStatement(stmt); } + catch (...) {} + } + + printf("DEBUG: Returning -1 due to unknown error\n"); + fflush(stdout); + return -1; + } +} + + + + + + + + + +}; // end of class occidml + + +//int main (void) +//{ +// string user = "scott"; +// string passwd = "tiger"; +// string db = ""; +// try{ +// cout << "occidml - Exhibiting simple insert, delete & update operations" +// << endl; +// occidml *demo = new occidml (user, passwd, db); +// cout << "Displaying all records before any operation" << endl; +// demo->displayAllRows (); +// +// cout << "Inserting a record into the table author_tab " +// << endl; +// demo->insertRow (); +// +// cout << "Displaying the records after insert " << endl; +// demo->displayAllRows (); +// +// cout << "Inserting a records into the table author_tab using dynamic bind" +// << endl; +// demo->insertBind (222, "ANAND"); +// +// cout << "Displaying the records after insert using dynamic bind" << endl; +// demo->displayAllRows (); +// +// cout << "deleting a row with author_id as 222 from author_tab table" << endl; +// demo->deleteRow (222, "ANAND"); +// +// cout << "updating a row with author_id as 444 from author_tab table" << endl; +// demo->updateRow (444, "ADAM"); +// +// cout << "displaying all rows after all the operations" << endl; +// demo->displayAllRows (); +// +// cout << "inserting radio active element properties" << endl; +// demo->insertElement ("Uranium", 12.572, 238.0289 ); +// demo->insertElement ("Plutonium", 12.12, 244.0642 ); +// demo->insertElement ("Curium", 18.17, 247.0703 ); +// demo->insertElement ("Thorium"); +// demo->insertElement ("Radium", 41.337, 226.0254); +// +// cout << "displaying all radio active element properties" << endl; +// demo->displayElements (); +// +// delete (demo); +// } +// catch (SQLException ex){ +// cout << ex.getMessage() << endl; +// } +// cout << "occidml - done" << endl; +//} diff --git a/CONNOR_ITK/ocilib.cxx b/CONNOR_ITK/ocilib.cxx new file mode 100644 index 0000000..0415047 --- /dev/null +++ b/CONNOR_ITK/ocilib.cxx @@ -0,0 +1,511 @@ +/*===================================================================================================================== + Copyright(c) 2012 ORIGIN. + Unpublished - All rights reserved +======================================================================================================================= +File description: + + Filename: ocilib.cxx + Module : OCI + + This file describes OCI library Package. + +======================================================================================================================= +Date Name Description of Change +1-Feb-2015 Ray li Initialize creation +$HISTORY$ +=====================================================================================================================*/ +#include "ocilib.h" +#include + + +#define NUM 100 +#define USERNAME "infodba" +#define PASSWORD "infodba" +#define DBNAME "tc" + + +// ṹ +typedef struct { + OCIEnv* p_env; //OCI environment handle + OCIError* p_err; //OCI error handle + OCISvcCtx* p_svc; //OCI service context handel ľ + OCIServer* p_ser; //OCI server handle + OCISession* p_usr; //OCI user session handle ûỰ + OCIStmt* p_sql; //OCI statement handle + OCIDefine* p_dfn; //OCI define handle + OCIBind* p_bnd; //OCI bind handle 󶨾 +}OCIHandleInfo; + + +// ṹ +typedef struct { + OCIEnv* p_env; + OCIError* p_err; + OCISvcCtx* p_svc; + OCIStmt* p_sql; + OCIDefine* p_dfn; + OCIBind* p_bnd; +}OCIDATA; + + +// ִʱ +typedef struct { + char value[NUM][NUM]; + char type[NUM][NUM]; +}SqlField; + + +// ѯʱ, +typedef struct { + int naIntValue[NUM]; + int nIntNum; + char caCharValue[500][500]; + int nCharNum; +}SqlSelField; + +OCIHandleInfo* ociHandle = NULL; +OCIHandleInfo ociHand; + +int InitHandle(); +int _ExeSQL(char* SQL, char** inputValue, int inputValueCount); +int _QuerySQL(char* SQL, SqlSelField* pOutField, SqlSelField* pSelField); +int GetDataFromQuery(int* pRc, SqlSelField* pOutField); +void QuitFreeHandle(); + + + + +/**************************************************************************************************************************************** +ƣ +ܣ +ڲ +ڲ + ע +*****************************************************************************************************************************************/ + + +// ʼHandler +int InitHandle() +{ + int swResult; + + ociHandle = &ociHand; + + + /*create OCI environment*/ + if (swResult = OCIEnvCreate(&ociHandle->p_env, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL)) // + { + printf("environment create error!\n\n"); + return -1; + } + else + { + printf("environment create success!\n\n"); + //return 0; + } + + /*init handle*/ + if (swResult = OCIHandleAlloc(ociHandle->p_env, (dvoid**)&ociHandle->p_ser, OCI_HTYPE_SERVER, 0, NULL)) // + { + printf("init server handle error!\n\n"); + return -1; + } + + + if (swResult = OCIHandleAlloc(ociHandle->p_env, (dvoid**)&ociHandle->p_err, OCI_HTYPE_ERROR, 0, NULL)) // + { + printf("init error handle error!\n\n"); + return -1; + } + + + if (swResult = OCIHandleAlloc(ociHandle->p_env, (dvoid**)&ociHandle->p_usr, OCI_HTYPE_SESSION, 0, NULL)) // + { + printf("init session handle error!\n\n"); + return -1; + } + + + if (swResult = OCIHandleAlloc(ociHandle->p_env, (dvoid**)&ociHandle->p_svc, OCI_HTYPE_SVCCTX, 0, NULL)) //ľ + { + printf("init service context handle error!\n\n"); + return -1; + } + + + if (swResult = OCIHandleAlloc(ociHandle->p_env, (dvoid**)&ociHandle->p_sql, OCI_HTYPE_STMT, 0, NULL)) //SQL + { + printf("init statement handle error!\n\n"); + return -1; + } + + printf("init handle success!\n\n"); + + return 0; +} + + + +// ݿ +int ConnServer(char* username, char* password, char* dbname) +{ + int swResult; + char errbuf[100] = { 0 }; + int errcode; + + if (InitHandle() == -1)//ʼ + return -1; + + if (swResult = OCILogon(ociHandle->p_env, ociHandle->p_err, &ociHandle->p_svc, (text*)username, strlen(username), (text*)password, strlen(password), (text*)dbname, strlen(dbname))) + { + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("Error - %.*s/n", 512, errbuf); + return -1; + } + else + printf("ݿӳɹ!\n\n"); + return 0; +} + + + +// SQLij(ִSQL) +int _ExeSQL(char* SQL, char** inputValue, int inputValueCount) +{ + int swResult, i; + int errcode; + + //ð󶨱 + OCIBind* p_bndp[100]; + + //׼SQL + if (swResult = OCIStmtPrepare(ociHandle->p_sql, ociHandle->p_err, (text*)SQL, strlen(SQL), OCI_NTV_SYNTAX, OCI_DEFAULT)) + { + printf("prepare SQL statements error!\n\n"); + } + else + { + printf("prepare SQL statements success!\n\n"); + } + + + // + for (i = 0; i < inputValueCount; i++) + { + char errbuf[100] = { 0 }; + if (swResult = OCIBindByPos(ociHandle->p_sql, &p_bndp[i], ociHandle->p_err, i + 1, (dvoid*)inputValue[i], (sb4)strlen(inputValue[i]) + 1, SQLT_STR, (dvoid*)0, (ub2*)0, (ub2*)0, (ub4)0, (ub4*)0, OCI_DEFAULT)) + { + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("Bind Error - %.*s/n", 512, errbuf); + return -1; + } + } + + //ִSQL statements + if (swResult = OCIStmtExecute(ociHandle->p_svc, ociHandle->p_sql, ociHandle->p_err, 1, 0, NULL, NULL, OCI_DEFAULT)) + { + char errbuf[100] = { 0 }; + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("execute SQL statement Error - %.*s\n", 512, errbuf); + return -1; + } + else + { + printf("execute SQL statement success!\n\n"); + } + return 0; +} + + + + +// ѯSQL +int _QuerySQL(char* SQL, SqlSelField* pOutField, SqlSelField* pSelField) +{ + sword status; + int rc = 0, ret = 0; + char errbuf[100] = { 0 }; + int maxNum = 2048; + char chTag[8]; + int iIndex = 0; + int outputColumn = 0; + int errcode = 0; + char nullValue = '\0'; // + sb2 sb2aInd[30] = { '\0' }; + + // ׼SQL + status = OCIStmtPrepare(ociHandle->p_sql, ociHandle->p_err, (text*)SQL, (ub4)strlen(SQL), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); + printf("sql1\n"); + if (status != OCI_SUCCESS) + { + printf("SQL Preparing failed\n"); + return -1; + } + + printf("sql2\n"); + // int͵, SQLʱ :1,:2, + for (iIndex = 0; iIndex < pSelField->nIntNum; iIndex++) + { + printf("sql3\n"); + memset(chTag, 0, 8); + sprintf(chTag, ":%d", iIndex + 1); + printf("sql4\n"); + if (rc = OCIBindByName(ociHandle->p_sql, (OCIBind**)&ociHandle->p_dfn, ociHandle->p_err, (text*)chTag, (sb4)strlen((char*)chTag), (dvoid*)&pSelField->naIntValue[iIndex], sizeof(int), SQLT_INT, (dvoid*)0, (ub2*)0, (ub2*)0, (ub4)0, (ub4*)0, OCI_DEFAULT)) + { + printf("sql5\n"); + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("BindByPos Error of ociHandle->p_sql - %.*s\n", 512, errbuf); + return -1; + } + } + printf("sql6\n"); + // char *͵, SQLʱ :3,:4, + for (iIndex = 0; iIndex < pSelField->nCharNum; iIndex++) + { + printf("sql7\n"); + int n = 0; + memset(chTag, 0, 8); + printf("sql8\n"); + n = pSelField->nIntNum + iIndex + 1; + printf("sql9\n"); + sprintf(chTag, ":%d", n); + printf("sql10\n"); + if (rc = OCIBindByName(ociHandle->p_sql, (OCIBind**)&ociHandle->p_dfn, ociHandle->p_err, (text*)chTag, (sb4)strlen((char*)chTag), (dvoid*)&pSelField->caCharValue[iIndex], NUM, SQLT_STR, (dvoid*)0, (ub2*)0, (ub2*)0, (ub4)0, (ub4*)0, OCI_DEFAULT)) + { + printf("sql11\n"); + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("BindByPos Error of ociHandle->p_sql - %.*s\n", 512, errbuf); + return -1; + } + } + + printf("sql12\n"); + // ִSQL + if (rc = OCIStmtExecute(ociHandle->p_svc, ociHandle->p_sql, ociHandle->p_err, (ub4)0, (ub4)0, (CONST OCISnapshot*) NULL, (OCISnapshot*)NULL, OCI_STMT_SCROLLABLE_READONLY)) + { + printf("sql13\n"); + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("execute SQL Error - %.*s\n", 512, errbuf); + return -1; + } + else + { + printf("execute SQL success!\n\n"); + } + printf("sql14\n"); + + if (ret = OCIAttrGet(ociHandle->p_sql, (ub4)OCI_HTYPE_STMT, (dvoid*)&outputColumn, (ub4*)0, (ub4)OCI_ATTR_PARAM_COUNT, ociHandle->p_err)) + { + printf("sql5\n"); + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("Get OCIAttr Error of ociHandle->p_sql - %.*s\n", 512, errbuf); + return -1; + } + printf("sql1\n"); + + // int͵, SQLʱ :1,:2, + for (iIndex = 0; iIndex < pOutField->nIntNum; iIndex++) + { + if (rc = OCIDefineByPos(ociHandle->p_sql, &ociHandle->p_dfn, ociHandle->p_err, iIndex + 1, (dvoid*)&pOutField->naIntValue[iIndex], sizeof(int), SQLT_INT, (dvoid*)0, (ub2*)0, (ub2*)0, OCI_DEFAULT)) + { + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("DefineByPos Error of ociHandle->p_sql - %.*s\n", 512, errbuf); + return -1; + } + } + printf("sql2\n"); + + // char *͵, SQLʱ :1,:2, + for (iIndex = 0; iIndex < outputColumn; iIndex++) + { + int n = iIndex + 1; + if (rc = OCIDefineByPos(ociHandle->p_sql, &ociHandle->p_dfn, ociHandle->p_err, n, (dvoid*)&pOutField->caCharValue[iIndex], 1000 * sizeof(char), SQLT_STR, (dvoid*)0, (ub2*)0, (ub2*)0, OCI_DEFAULT)) + { + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("DefineByPos Error of ociHandle->p_sql - %.*s\n", 512, errbuf); + return -1; + } + } + printf("sql3\n"); + + return 0; + +} + + + +// ͷHandler +void QuitFreeHandle() +{ + // ˳ + OCILogoff(ociHandle->p_svc, ociHandle->p_err); + printf("Quit success!\n"); + + // ͷž + OCIHandleFree(ociHandle->p_ser, OCI_HTYPE_SERVER); //ͷŷ + OCIHandleFree(ociHandle->p_err, OCI_HTYPE_ERROR); //ͷŴ + OCIHandleFree(ociHandle->p_usr, OCI_HTYPE_SESSION); //ͷ + OCIHandleFree(ociHandle->p_svc, OCI_HTYPE_SVCCTX); //ͷľ + OCIHandleFree(ociHandle->p_sql, OCI_HTYPE_STMT); //ͷSQL +} + + +//ع +int ExecuteRollback() { + int swResult, i; + int errcode; + + if (swResult = OCITransRollback(ociHandle->p_svc, ociHandle->p_err, 0)) + { + char errbuf[100] = { 0 }; + OCIErrorGet((dvoid*)ociHandle->p_err, (ub4)1, (text*)NULL, &errcode, (ub1*)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); + printf("Rollback SQL statement Error - %.*s\n", 512, errbuf); + return -1; + } + else + { + printf("Rollback SQL statement success!\n\n"); + } + return 0; +} + + + +// ִ +int ExecuteSQL(char* SQL, int valueCount, char** value) +{ + int i = 0; + + if (i = _ExeSQL(SQL, value, valueCount)) + { + printf("\n"); + //QuitFreeHandle();//ͷȨ,עӰɹ + return -1; + } + printf("2\n"); + return 0; +} + + + +// ִ +int ExecuteSQL2(char* SQL, int valueCount, char** value) +{ + int i = 0; + + if (i = _ExeSQL(SQL, value, valueCount)) + { + printf("󣬿ʼع\n"); + ExecuteRollback(); + //QuitFreeHandle(); + return -1; + } + printf("2\n"); + return 0; +} + + +// IJѯ +int QuerySQL(char* SQL, int inputValueCount, char** inputValue, int* outputColumn, int* outputValueCount, char**** outputValue) +{ + int i = 0, j = 0, ret = 0; + + int times = 0, temp = 0; + + SqlSelField infield; + SqlSelField outField; + + // ʼṹ + infield.nCharNum = inputValueCount; + infield.nIntNum = 0; + outField.nCharNum = 0; + outField.nIntNum = 0; + + *outputColumn = 0; + *outputValueCount = 0; + + for (i = 0; i < inputValueCount; i++) + { + strcpy(infield.caCharValue[i], inputValue[i]); + } + + // ִвѯ + printf("1\n"); + + if (ret = _QuerySQL(SQL, &outField, &infield)) + { + printf("SQLѯʧ!\n"); + QuitFreeHandle(); + return -1; + } + printf("2\n"); + // ȡ + ret = OCIAttrGet(ociHandle->p_sql, (ub4)OCI_HTYPE_STMT, (dvoid*)outputColumn, (ub4*)0, (ub4)OCI_ATTR_PARAM_COUNT, ociHandle->p_err); + printf("3\n"); + // ȡһ,ȥ + ret = OCIStmtFetch2(ociHandle->p_sql, ociHandle->p_err, 1, OCI_FETCH_LAST, 0, OCI_DEFAULT); + // ȡ + printf("4\n"); + ret = OCIAttrGet(ociHandle->p_sql, (ub4)OCI_HTYPE_STMT, (dvoid*)outputValueCount, (ub4*)0, (ub4)OCI_ATTR_ROW_COUNT, ociHandle->p_err); + printf("5\n"); + if (*outputValueCount == 0) + return 0; + + i = 0;//2022/3/3 + // ʼڴ沢Ҵ洢 + printf("6\n"); + ret = OCIStmtFetch2(ociHandle->p_sql, ociHandle->p_err, 1, OCI_FETCH_FIRST, 0, OCI_DEFAULT); + printf("7\n"); + *outputValue = (char***)calloc((*outputValueCount) + 1, sizeof(char**)); + do + { + (*outputValue)[i] = (char**)calloc((*outputColumn) + 1, sizeof(char*)); + printf("8\n"); + for (j = 0; j < (*outputColumn); j++) + { + printf("9\n"); + (*outputValue)[i][j] = (char*)calloc(6000, sizeof(char)); + printf("10\n"); + strcpy((*outputValue)[i][j], outField.caCharValue[j]); + printf("11\n"); + //printf("outValue[%d][%d] = %s , ַ=%d, ַָ= %d\n ",i,j,(*outputValue)[i][j],&(*outputValue)[i][j],(*outputValue)[i][j]); + } + i++; + } while ((ret = OCIStmtFetch2(ociHandle->p_sql, ociHandle->p_err, 1, OCI_FETCH_NEXT, 1, OCI_DEFAULT) != OCI_NO_DATA)); + printf("12\n"); + + + + return 0; +} + + +// IJѯ +int QuerySQLNoInputParam(char* SQL, int* outputColumn, int* outputValueCount, char**** outputValue) +{ + return QuerySQL(SQL, 0, NULL, outputColumn, outputValueCount, outputValue); +} + +// ޲ +int ExecuteSQLNoInputParam(char* SQL) +{ + printf("ʼ\n"); + return ExecuteSQL(SQL, 0, NULL); +} + +// ޲2ع +int ExecuteSQLNoInputParam2(char* SQL) +{ + printf("ʼ2\n"); + return ExecuteSQL2(SQL, 0, NULL); +} + + + +// Ͽ +void DisConnServer() +{ + if (ociHandle != NULL) + QuitFreeHandle(); +} + diff --git a/CONNOR_ITK/ocilib.h b/CONNOR_ITK/ocilib.h new file mode 100644 index 0000000..8ceb8d1 --- /dev/null +++ b/CONNOR_ITK/ocilib.h @@ -0,0 +1,115 @@ +/*===================================================================================================================== + Copyright(c) 2012 ORIGIN. + Unpublished - All rights reserved +======================================================================================================================= +File description: + + Filename: ocilib.h + Module : OCI + + This Header file of OCI library Package. + +======================================================================================================================= +Date Name Description of Change +1-Feb-2015 Ray Initialize creation +$HISTORY$ +=====================================================================================================================*/ +#include +#include +#include +#include +#include +//#include + +#define OCI_FAIL 1 +#define OCI_OK 0 + +#ifdef __cplusplus +extern "C" +{ +#endif + /** + * ݿ. + * @param username - û + * @param password - + * @param dbname - ݿSID + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ConnServer(char *username,char *password,char *dbname); + + + /** + * ִSQL. + * @param SQL - SQL + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ExecuteSQLNoInputParam(char *SQL); + + /** + * ִSQL2. + * @param SQL - SQL + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ExecuteSQLNoInputParam2(char *SQL); + + /** + * ִSQL. + * @param SQL - SQL + * @param inputValueCount - + * @param inputValue - ֵ + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ExecuteSQL(char *SQL,int inputValueCount,char **inputValue); + + /** + * IJѯSQL. + * @param SQL - SQL + * @param outputColumn - е + * @param outputValueCount - е + * @param outputValue - + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int QuerySQLNoInputParam(char *SQL, int * outputColumn, int * outputValueCount, char **** outputValue); + + /** + * IJѯSQL. + * @param SQL - SQL + * @param inputValueCount - + * @param inputValue - ֵ + * @param outputColumn - е + * @param outputValueCount - е + * @param outputValue - + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int QuerySQL(char *SQL, int inputValueCount, char ** inputValue, int * outputColumn, int * outputValueCount, char **** outputValue); + + /** + * Ͽݿ. + * + * ORACLE ݿװ + */ + extern void DisConnServer(); + + + /** + * عǰݿ. + * + * ORACLE ݿװ + */ + extern int ExecuteRollback(); + +#ifdef __cplusplus +} +#endif diff --git a/CONNOR_ITK/ocilib2.h b/CONNOR_ITK/ocilib2.h new file mode 100644 index 0000000..0b525ba --- /dev/null +++ b/CONNOR_ITK/ocilib2.h @@ -0,0 +1,68 @@ +/* + * OCILIB - C Driver for Oracle (C Wrapper for Oracle OCI) + * + * Website: http://www.ocilib.net + * + * Copyright (c) 2007-2020 Vincent ROGIER + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* IMPORTANT NOTICE + * + * This file contains explanations about Oracle and OCI technologies. + * OCILIB is a wrapper around OCI and thus exposes OCI features. + * The OCILIB documentation intends to explain Oracle / OCI concepts + * and is naturally based on the official Oracle OCI documentation. + * + * Some parts of OCILIB documentation may include some information + * taken and adapted from the following Oracle documentations : + * - Oracle Call Interface Programmer's Guide + * - Oracle Streams - Advanced Queuing User's Guide + */ + +#ifndef OCILIB_H_INCLUDED +#define OCILIB_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup OcilibCApi C API + * @{ + * + */ + +/** +* @defgroup OcilibCApiSupportedCharsets Character sets +* @defgroup OcilibCApiDatatypes Data types +* @defgroup OcilibCApiEnvironmentVariables Environment Variables +*/ + +#include "ocilibc/platform.h" +#include "ocilibc/defines.h" +#include "ocilibc/types.h" +#include "ocilibc/api.h" +#include "ocilibc/compat.h" + +#ifdef __cplusplus +} +#endif + +/** + * @} OcilibCApi + */ + + +#endif /* OCILIB_H_INCLUDED */ diff --git a/CONNOR_ITK/ocilib2.hpp b/CONNOR_ITK/ocilib2.hpp new file mode 100644 index 0000000..ef39569 --- /dev/null +++ b/CONNOR_ITK/ocilib2.hpp @@ -0,0 +1,218 @@ +/* + * OCILIB - C Driver for Oracle (C Wrapper for Oracle OCI) + * + * Website: http://www.ocilib.net + * + * Copyright (c) 2007-2020 Vincent ROGIER + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * IMPORTANT NOTICE + * + * This C++ header defines C++ wrapper classes around the OCILIB C API + * It requires a compatible version of OCILIB + * + */ + +#ifndef OCILIBCPP_H_INCLUDED +#define OCILIBCPP_H_INCLUDED + +/** + * @namespace ocilib + * @brief OCILIB ++ Namespace + * + */ + +namespace ocilib +{ + +/** + * @defgroup OcilibCppApi C++ API + * @{ + */ + +/** + * @defgroup OcilibCppApiOverview Overview + * @{ + * + * @par Introduction + * OCILIB++ is a C++ API for Oracle built on top of the C OCILIB API: + * - Full C API ported to C++ + * - Implemented as a set of header files, no library compilation needed + * - Based on C++ and STL paradigms (Strong typing, templates, containers, RAII, exception handling, operators, stack objects) + * - Based on design patterns (RAII, delegation, reference counting, smart pointers, proxies, singleton) + * - No user dynamic object allocation required + * - The only dependencies are : STL and OCILIB C API + * + * @par C++ language requirements + * - The OCILIB C++ API requires only C++03 features. + * - It does not required C++11/14/17 but uses some CXX features when target compiler support them + * + * @par Reference counting model + * - API usage is very simple, based on stack objects wrapping OCILIB handles using reference counting. + * - OCILIB handles are automatically allocated internally by C++ objects constructors or methods. + * - They are also automatically freed when the last C++ object referencing it goes out of scope. + * - Dynamic memory allocation is not required at all. + * - OCILIB++ allows simple and safe usage of Oracle client without the worries of memory leakages. + * - Using stack objects also makes error handling easier and program logic more robust + * + * @par C++ API classes usage + * Most C++ API classes wrap C API handles. + * When instances are created using the default constructors, they hold no C handles and have + * their method IsNull() returning true. + * Any use of other methods and functions on such object methods will throw an C++ exception. + * Thus, in order to have a valid object : + * - use a parametrized constructor + * - use the default constructor and then later assign a value to the instance using assignment operator. + * In the later case, the value can be provided by a function return value or using the object class constructor + * + * @par Exception model + * - Any failure occurring within an OCILIB C API call will throw a ocilib::Exception + * - For conformance reasons, this class derives from std::Exception + * + * @warning + * - OCILIB++ wraps the whole OCILIB C API. + * - Each C OCILIB object handle has its C++ class counter part. + * - The whole OCILIB C Documentation (concepts, use cases, features) is still valid for OCILIB++ + * + * @} OcilibCppApiOverview + */ + +/** + * @defgroup OcilibCppApiMainDemoApplication OCILIB main C++ demo application code + * @{ + * + * Main C++ demo source + * @include ocilib_demo.cpp + * + * @} OcilibCppApiMainDemoApplication + */ + + /** + * @defgroup OcilibCppApiDemoListApplication Some OCILIB C++ sample codes + * @{ + * + * Here are some C++ samples code. More samples can be found under the demo folder of ocilib packages. + * + * @par Fetching data + * @include fetch.cpp + * + * @par Binding vectors + * @include array.cpp + * + * @par Using collections + * @include coll.cpp + * + * @par Using connection pools + * @include pool.cpp + * + * @par Oracle 12c Implicit resultsets + * @include implicit_resultset.cpp + * + * @par Using Oracle objects + * @include object.cpp + * + * @par Database notifications + * @include notification.cpp + * + * @} OcilibCppApiDemoListApplication + */ + + /** + * + * @} OcilibCppApi + */ + +} + +/* + * IMPORTANT NOTICE + * + * This C++ header defines C++ wrapper classes around the OCILIB C API + * It requires a compatible version of OCILIB + * + */ + +/* Including declarations */ + +#include "ocilibcpp/config.hpp" +#include "ocilibcpp/core.hpp" +#include "ocilibcpp/support.hpp" +#include "ocilibcpp/types.hpp" + +/* Including core implementations */ + +#include "ocilibcpp/detail/core/Utils.hpp" +#include "ocilibcpp/detail/core/Enum.hpp" +#include "ocilibcpp/detail/core/Flags.hpp" +#include "ocilibcpp/detail/core/ManagedBuffer.hpp" +#include "ocilibcpp/detail/core/HandleHolder.hpp" +#include "ocilibcpp/detail/core/Locker.hpp" +#include "ocilibcpp/detail/core/Lockable.hpp" +#include "ocilibcpp/detail/core/ConcurrentMap.hpp" +#include "ocilibcpp/detail/core/ConcurrentList.hpp" +#include "ocilibcpp/detail/core/SmartHandle.hpp" +#include "ocilibcpp/detail/core/MemoryDebugInfo.hpp" + +/* Including support implementations */ + +#include "ocilibcpp/detail/support/BindResolver.hpp" +#include "ocilibcpp/detail/support/BindObject.hpp" +#include "ocilibcpp/detail/support/BindArray.hpp" +#include "ocilibcpp/detail/support/BindObjectAdaptor.hpp" +#include "ocilibcpp/detail/support/BindTypeAdaptor.hpp" +#include "ocilibcpp/detail/support/BindsHolder.hpp" +#include "ocilibcpp/detail/support/NumericTypeResolver.hpp" + +/* Including types implementations */ + +#include "ocilibcpp/detail/Exception.hpp" +#include "ocilibcpp/detail/Environment.hpp" +#include "ocilibcpp/detail/Mutex.hpp" +#include "ocilibcpp/detail/Thread.hpp" +#include "ocilibcpp/detail/ThreadKey.hpp" +#include "ocilibcpp/detail/Pool.hpp" +#include "ocilibcpp/detail/Connection.hpp" +#include "ocilibcpp/detail/Transaction.hpp" +#include "ocilibcpp/detail/Number.hpp" +#include "ocilibcpp/detail/Date.hpp" +#include "ocilibcpp/detail/Interval.hpp" +#include "ocilibcpp/detail/Timestamp.hpp" +#include "ocilibcpp/detail/Lob.hpp" +#include "ocilibcpp/detail/File.hpp" +#include "ocilibcpp/detail/TypeInfo.hpp" +#include "ocilibcpp/detail/Object.hpp" +#include "ocilibcpp/detail/Reference.hpp" +#include "ocilibcpp/detail/Collection.hpp" +#include "ocilibcpp/detail/CollectionIterator.hpp" +#include "ocilibcpp/detail/CollectionElement.hpp" +#include "ocilibcpp/detail/Long.hpp" +#include "ocilibcpp/detail/BindInfo.hpp" +#include "ocilibcpp/detail/Statement.hpp" +#include "ocilibcpp/detail/Resultset.hpp" +#include "ocilibcpp/detail/Column.hpp" +#include "ocilibcpp/detail/Subscription.hpp" +#include "ocilibcpp/detail/Event.hpp" +#include "ocilibcpp/detail/Agent.hpp" +#include "ocilibcpp/detail/Message.hpp" +#include "ocilibcpp/detail/Enqueue.hpp" +#include "ocilibcpp/detail/Dequeue.hpp" +#include "ocilibcpp/detail/DirectPath.hpp" +#include "ocilibcpp/detail/Queue.hpp" +#include "ocilibcpp/detail/QueueTable.hpp" + + +#endif + diff --git a/CONNOR_ITK/tinystr.cpp b/CONNOR_ITK/tinystr.cpp new file mode 100644 index 0000000..0665768 --- /dev/null +++ b/CONNOR_ITK/tinystr.cpp @@ -0,0 +1,111 @@ +/* +www.sourceforge.net/projects/tinyxml + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TIXML_USE_STL + +#include "tinystr.h" + +// Error value for find primitive +const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); + + +// Null rep. +TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; + + +void TiXmlString::reserve (size_type cap) +{ + if (cap > capacity()) + { + TiXmlString tmp; + tmp.init(length(), cap); + memcpy(tmp.start(), data(), length()); + swap(tmp); + } +} + + +TiXmlString& TiXmlString::assign(const char* str, size_type len) +{ + size_type cap = capacity(); + if (len > cap || cap > 3*(len + 8)) + { + TiXmlString tmp; + tmp.init(len); + memcpy(tmp.start(), str, len); + swap(tmp); + } + else + { + memmove(start(), str, len); + set_size(len); + } + return *this; +} + + +TiXmlString& TiXmlString::append(const char* str, size_type len) +{ + size_type newsize = length() + len; + if (newsize > capacity()) + { + reserve (newsize + capacity()); + } + memmove(finish(), str, len); + set_size(newsize); + return *this; +} + + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) +{ + TiXmlString tmp; + tmp.reserve(a.length() + b.length()); + tmp += a; + tmp += b; + return tmp; +} + +TiXmlString operator + (const TiXmlString & a, const char* b) +{ + TiXmlString tmp; + TiXmlString::size_type b_len = static_cast( strlen(b) ); + tmp.reserve(a.length() + b_len); + tmp += a; + tmp.append(b, b_len); + return tmp; +} + +TiXmlString operator + (const char* a, const TiXmlString & b) +{ + TiXmlString tmp; + TiXmlString::size_type a_len = static_cast( strlen(a) ); + tmp.reserve(a_len + b.length()); + tmp.append(a, a_len); + tmp += b; + return tmp; +} + + +#endif // TIXML_USE_STL diff --git a/CONNOR_ITK/tinystr.h b/CONNOR_ITK/tinystr.h new file mode 100644 index 0000000..89cca33 --- /dev/null +++ b/CONNOR_ITK/tinystr.h @@ -0,0 +1,305 @@ +/* +www.sourceforge.net/projects/tinyxml + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include +#include + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/CONNOR_ITK/tinyxml.cpp b/CONNOR_ITK/tinyxml.cpp new file mode 100644 index 0000000..fb3ed5a --- /dev/null +++ b/CONNOR_ITK/tinyxml.cpp @@ -0,0 +1,1886 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include + +#ifdef TIXML_USE_STL +#include +#include +#endif + +#include "tinyxml.h" + +FILE* TiXmlFOpen( const char* filename, const char* mode ); + +bool TiXmlBase::condenseWhiteSpace = true; + +// Microsoft compiler security +FILE* TiXmlFOpen( const char* filename, const char* mode ) +{ + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + FILE* fp = 0; + errno_t err = fopen_s( &fp, filename, mode ); + if ( !err && fp ) + return fp; + return 0; + #else + return fopen( filename, mode ); + #endif +} + +void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); + #else + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + #endif + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append( buf, (int)strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} + + +TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::CopyTo( TiXmlNode* target ) const +{ + target->SetValue (value.c_str() ); + target->userData = userData; + target->location = location; +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + assert( node->parent == 0 || node->parent == this ); + assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); + + if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + delete node; + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( !replaceThis ) + return 0; + + if ( replaceThis->parent != this ) + return 0; + + if ( withThis.ToDocument() ) { + // A document can never be a child. Thanks to Noam. + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( !removeThis ) { + return false; + } + + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + //delete removeThis; kk Ҫɾ + return true; +} + +const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + + +const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +void TiXmlElement::RemoveAttribute( const char * name ) +{ + #ifdef TIXML_USE_STL + TIXML_STRING str( name ); + TiXmlAttribute* node = attributeSet.Find( str ); + #else + TiXmlAttribute* node = attributeSet.Find( name ); + #endif + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +const TiXmlElement* TiXmlNode::FirstChildElement() const +{ + const TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + const TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElement::TiXmlElement (const char * _value) + : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + + +#ifdef TIXML_USE_STL +TiXmlElement::TiXmlElement( const std::string& _value ) + : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} +#endif + + +TiXmlElement::TiXmlElement( const TiXmlElement& copy) + : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) +{ + firstChild = lastChild = 0; + copy.CopyTo( this ); +} + + +TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base ) +{ + ClearThis(); + base.CopyTo( this ); + return *this; +} + + +TiXmlElement::~TiXmlElement() +{ + ClearThis(); +} + + +void TiXmlElement::ClearThis() +{ + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + + +const char* TiXmlElement::Attribute( const char* name ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return node->Value(); + return 0; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( attrib ) + return &attrib->ValueStr(); + return 0; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, int* i ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const char* result = 0; + + if ( attrib ) { + result = attrib->Value(); + if ( i ) { + attrib->QueryIntValue( i ); + } + } + return result; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const std::string* result = 0; + + if ( attrib ) { + result = &attrib->ValueStr(); + if ( i ) { + attrib->QueryIntValue( i ); + } + } + return result; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, double* d ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const char* result = 0; + + if ( attrib ) { + result = attrib->Value(); + if ( d ) { + attrib->QueryDoubleValue( d ); + } + } + return result; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const std::string* result = 0; + + if ( attrib ) { + result = &attrib->ValueStr(); + if ( d ) { + attrib->QueryDoubleValue( d ); + } + } + return result; +} +#endif + + +int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryIntValue( ival ); +} + + +int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + int ival = 0; + int result = node->QueryIntValue( &ival ); + *value = (unsigned)ival; + return result; +} + + +int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + int result = TIXML_WRONG_TYPE; + if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) ) + { + *bval = true; + result = TIXML_SUCCESS; + } + else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) ) + { + *bval = false; + result = TIXML_SUCCESS; + } + return result; +} + + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryIntValue( ival ); +} +#endif + + +int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryDoubleValue( dval ); +} + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryDoubleValue( dval ); +} +#endif + + +void TiXmlElement::SetAttribute( const char * name, int val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetIntValue( val ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, int val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetIntValue( val ); + } +} +#endif + + +void TiXmlElement::SetDoubleAttribute( const char * name, double val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetDoubleValue( val ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetDoubleAttribute( const std::string& name, double val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetDoubleValue( val ); + } +} +#endif + + +void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname ); + if ( attrib ) { + attrib->SetValue( cvalue ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name ); + if ( attrib ) { + attrib->SetValue( _value ); + } +} +#endif + + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + assert( cfile ); + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } +} + + +void TiXmlElement::CopyTo( TiXmlElement* target ) const +{ + // superclass: + TiXmlNode::CopyTo( target ); + + // Element class: + // Clone the attributes, then clone the children. + const TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + +bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this, attributeSet.First() ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +const char* TiXmlElement::GetText() const +{ + const TiXmlNode* child = this->FirstChild(); + if ( child ) { + const TiXmlText* childText = child->ToText(); + if ( childText ) { + return childText->Value(); + } + } + return 0; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = true; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = true; + value = documentName; + ClearError(); +} + + +#ifdef TIXML_USE_STL +TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = true; + value = documentName; + ClearError(); +} +#endif + + +TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + copy.CopyTo( this ); +} + + +TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy ) +{ + Clear(); + copy.CopyTo( this ); + return *this; +} + + +bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) +{ + return LoadFile( Value(), encoding ); +} + + +bool TiXmlDocument::SaveFile() const +{ + return SaveFile( Value() ); +} + +bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) +{ + TIXML_STRING filename( _filename ); + value = filename; + + // reading in binary mode so that tinyxml can normalize the EOL + FILE* file = TiXmlFOpen( value.c_str (), "rb" ); + + if ( file ) + { + bool result = LoadFile( file, encoding ); + fclose( file ); + return result; + } + else + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } +} + +bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) +{ + if ( !file ) + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Delete the existing data: + Clear(); + location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length <= 0 ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // + // + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[ length+1 ]; + buf[0] = 0; + + if ( fread( buf, length, 1, file ) != 1 ) { + delete [] buf; + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Process the buffer in place to normalize new lines. (See comment above.) + // Copies from the 'p' to 'q' pointer, where p can advance faster if + // a newline-carriage return is hit. + // + // Wikipedia: + // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or + // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... + // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others + // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS + // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 + + const char* p = buf; // the read head + char* q = buf; // the write head + const char CR = 0x0d; + const char LF = 0x0a; + + buf[length] = 0; + while( *p ) { + assert( p < (buf+length) ); + assert( q <= (buf+length) ); + assert( q <= p ); + + if ( *p == CR ) { + *q++ = LF; + p++; + if ( *p == LF ) { // check for CR+LF (and skip LF) + p++; + } + } + else { + *q++ = *p++; + } + } + assert( q <= (buf+length) ); + *q = 0; + + Parse( buf, 0, encoding ); + + delete [] buf; + return !Error(); +} + + +bool TiXmlDocument::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = TiXmlFOpen( filename, "w" ); + if ( fp ) + { + bool result = SaveFile( fp ); + fclose( fp ); + return result; + } + return false; +} + + +bool TiXmlDocument::SaveFile( FILE* fp ) const +{ + if ( useMicrosoftBOM ) + { + const unsigned char TIXML_UTF_LEAD_0 = 0xefU; + const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; + const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + fputc( TIXML_UTF_LEAD_0, fp ); + fputc( TIXML_UTF_LEAD_1, fp ); + fputc( TIXML_UTF_LEAD_2, fp ); + } + Print( fp, 0 ); + return (ferror(fp) == 0); +} + + +void TiXmlDocument::CopyTo( TiXmlDocument* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->error = error; + target->errorId = errorId; + target->errorDesc = errorDesc; + target->tabsize = tabsize; + target->errorLocation = errorLocation; + target->useMicrosoftBOM = useMicrosoftBOM; + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + + +bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +const TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + +/* +TiXmlAttribute* TiXmlAttribute::Next() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} +*/ + +const TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + +/* +TiXmlAttribute* TiXmlAttribute::Previous() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} +*/ + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + TIXML_STRING n, v; + + EncodeString( name, &n ); + EncodeString( value, &v ); + + if (value.find ('\"') == TIXML_STRING::npos) { + if ( cfile ) { + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; + } + } + else { + if ( cfile ) { + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; + } + } +} + + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + char buf [64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); + #else + sprintf (buf, "%d", _value); + #endif + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + char buf [256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value); + #else + sprintf (buf, "%g", _value); + #endif + SetValue (buf); +} + +int TiXmlAttribute::IntValue() const +{ + return atoi (value.c_str ()); +} + +double TiXmlAttribute::DoubleValue() const +{ + return atof (value.c_str ()); +} + + +TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) +{ + copy.CopyTo( this ); +} + + +TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base ) +{ + Clear(); + base.CopyTo( this ); + return *this; +} + + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlComment::CopyTo( TiXmlComment* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + if ( cdata ) + { + int i; + fprintf( cfile, "\n" ); + for ( i=0; i\n", value.c_str() ); // unformatted output + } + else + { + TIXML_STRING buffer; + EncodeString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); + } +} + + +void TiXmlText::CopyTo( TiXmlText* target ) const +{ + TiXmlNode::CopyTo( target ); + target->cdata = cdata; +} + + +bool TiXmlText::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const char * _version, + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +#ifdef TIXML_USE_STL +TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} +#endif + + +TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) + : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) +{ + copy.CopyTo( this ); +} + + +TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) +{ + Clear(); + copy.CopyTo( this ); + return *this; +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + if ( cfile ) fprintf( cfile, "" ); + if ( str ) (*str) += "?>"; +} + + +void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->version = version; + target->encoding = encoding; + target->standalone = standalone; +} + + +bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + #ifdef TIXML_USE_STL + assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. + #else + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + #endif + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + + +#ifdef TIXML_USE_STL +TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + +TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name ) +{ + TiXmlAttribute* attrib = Find( _name ); + if ( !attrib ) { + attrib = new TiXmlAttribute(); + Add( attrib ); + attrib->SetName( _name ); + } + return attrib; +} +#endif + + +TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; +} + + +TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name ) +{ + TiXmlAttribute* attrib = Find( _name ); + if ( !attrib ) { + attrib = new TiXmlAttribute(); + Add( attrib ); + attrib->SetName( _name ); + } + return attrib; +} + + +#ifdef TIXML_USE_STL +std::istream& operator>> (std::istream & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; +} +#endif + + +#ifdef TIXML_USE_STL +std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out << printer.Str(); + + return out; +} + + +std::string& operator<< (std::string& out, const TiXmlNode& base ) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out.append( printer.Str() ); + + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) +{ + DoIndent(); + buffer += "<"; + buffer += element.Value(); + + for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) + { + buffer += " "; + attrib->Print( 0, 0, &buffer ); + } + + if ( !element.FirstChild() ) + { + buffer += " />"; + DoLineBreak(); + } + else + { + buffer += ">"; + if ( element.FirstChild()->ToText() + && element.LastChild() == element.FirstChild() + && element.FirstChild()->ToText()->CDATA() == false ) + { + simpleTextPrint = true; + // no DoLineBreak()! + } + else + { + DoLineBreak(); + } + } + ++depth; + return true; +} + + +bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) +{ + --depth; + if ( !element.FirstChild() ) + { + // nothing. + } + else + { + if ( simpleTextPrint ) + { + simpleTextPrint = false; + } + else + { + DoIndent(); + } + buffer += ""; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlText& text ) +{ + if ( text.CDATA() ) + { + DoIndent(); + buffer += ""; + DoLineBreak(); + } + else if ( simpleTextPrint ) + { + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + } + else + { + DoIndent(); + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) +{ + DoIndent(); + declaration.Print( 0, 0, &buffer ); + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlComment& comment ) +{ + DoIndent(); + buffer += ""; + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) +{ + DoIndent(); + buffer += "<"; + buffer += unknown.Value(); + buffer += ">"; + DoLineBreak(); + return true; +} + diff --git a/CONNOR_ITK/tinyxml.h b/CONNOR_ITK/tinyxml.h new file mode 100644 index 0000000..a3589e5 --- /dev/null +++ b/CONNOR_ITK/tinyxml.h @@ -0,0 +1,1805 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SNPRINTF snprintf + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 6; +const int TIXML_PATCH_VERSION = 2; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknown node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + TINYXML_DOCUMENT, + TINYXML_ELEMENT, + TINYXML_COMMENT, + TINYXML_UNKNOWN, + TINYXML_TEXT, + TINYXML_DECLARATION, + TINYXML_TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT, + TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* FindOrCreate( const char* _name ); + +# ifdef TIXML_USE_STL + TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* FindOrCreate( const std::string& _name ); +# endif + + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + TiXmlElement& operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute(). + int QueryUnsignedAttribute( const char* name, unsigned* _value ) const; + /** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). + Note that '1', 'true', or 'yes' are considered true, while '0', 'false' + and 'no' are considered false. + */ + int QueryBoolAttribute( const char* name, bool* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /// QueryStringAttribute examines the attribute - see QueryIntAttribute(). + int QueryStringAttribute( const char* name, std::string* _value ) const { + const char* cstr = Attribute( name ); + if ( cstr ) { + *_value = std::string( cstr ); + return TIXML_SUCCESS; + } + return TIXML_NO_ATTRIBUTE; + } + + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types that contain spaces. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + + int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + ///< STL std::string form. + void SetDoubleAttribute( const std::string& name, double value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + TiXmlComment& operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); } + TiXmlText& operator=( const TiXmlText& base ) { base.CopyTo( this ); return *this; } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + TiXmlDeclaration& operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); } + TiXmlUnknown& operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); return *this; } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + TiXmlDocument& operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i +#include + +#include "tinyxml.h" + +//#define DEBUG_PARSER +#if defined( DEBUG_PARSER ) +# if defined( DEBUG ) && defined( _MSC_VER ) +# include +# define TIXML_LOG OutputDebugString +# else +# define TIXML_LOG printf +# endif +#endif + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// Including the basic of this table, which determines the #bytes in the +// sequence from the lead byte. 1 placed for invalid sequences -- +// although the result will be junk, pass it through as much as possible. +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf + +const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +const int TiXmlBase::utf8ByteTable[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid +}; + + +void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } +} + + +/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } +} + + +/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } +} + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + void Stamp( const char* now, TiXmlEncoding encoding ); + + const TiXmlCursor& Cursor() const { return cursor; } + + private: + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Treat p as unsigned, so we have a happy compiler. + const unsigned char* pU = (const unsigned char*)p; + + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*pU) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case TIXML_UTF_LEAD_0: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) +{ + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + const unsigned char* pU = (const unsigned char*)p; + + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+2)==TIXML_UTF_LEAD_2 ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbeU ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbfU ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) ) + ++p; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; + + *tag += (char) in->get(); + } +} + +/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) +{ + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; +} +#endif + +// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The +// "assign" optimization removes over 10% of the execution time. +// +const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) +{ + // Oddly, not supported on some comilers, + //name->clear(); + // So use this: + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + const char* start = p; + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + //(*name) += *p; // expensive + ++p; + } + if ( p-start > 0 ) { + name->assign( start, p-start ); + } + return p; + } + return 0; +} + +const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) +{ + // Presume an entity, and pull it out. + TIXML_STRING ent; + int i; + *length = 0; + + if ( *(p+1) && *(p+1) == '#' && *(p+2) ) + { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) + { + // Hexadecimal. + if ( !*(p+3) ) return 0; + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != 'x' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; iappend( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + if ( p && *p ) + p += strlen( endTag ); + return ( p && *p ) ? p : 0; +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); +} + +#endif + +const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + const unsigned char* pU = (const unsigned char*)p; + if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 + && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 + && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) + { + encoding = TIXML_ENCODING_UTF8; + useMicrosoftBOM = true; + } + } + + p = SkipWhiteSpace( p, encoding ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // Was this empty? + if ( !firstChild ) { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); + return 0; + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p, encoding ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + p = SkipWhiteSpace( p, encoding ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + if ( document ) + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // [ 1475201 ] TinyXML parses entities in comments + // Oops - ReadText doesn't work, because we don't want to parse the entities. + // p = ReadText( p, &value, false, endTag, false, encoding ); + // + // from the XML spec: + /* + [Definition: Comments may appear anywhere in a document outside other markup; in addition, + they may appear within the document type declaration at places allowed by the grammar. + They are not part of the document's character data; an XML processor MAY, but need not, + make it possible for an application to retrieve the text of comments. For compatibility, + the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity + references MUST NOT be recognized within comments. + + An example of a comment: + + + */ + + value = ""; + // Keep all the white space. + while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) + { + value.append( p, 1 ); + ++p; + } + if ( p && *p ) + p += strlen( endTag ); + + return p; +} + + +const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + const char SINGLE_QUOTE = '\''; + const char DOUBLE_QUOTE = '\"'; + + if ( *p == SINGLE_QUOTE ) + { + ++p; + end = "\'"; // single quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == DOUBLE_QUOTE ) + { + ++p; + end = "\""; // double quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) // whitespace + && *p != '/' && *p != '>' ) // tag end + { + if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { + // [ 1451649 ] Attribute values with trailing quotes not handled correctly + // We did not have an opening quote but seem to have a + // closing one. Give up and throw an error. + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( !cdata && (c == '<' ) ) + { + return; + } + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); // "commits" the peek made above + + if ( cdata && c == '>' && tag->size() >= 3 ) { + size_t len = tag->size(); + if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { + // terminator of cdata. + return; + } + } + } +} +#endif + +const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + value = ""; + TiXmlDocument* document = GetDocument(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + const char* const startTag = ""; + + if ( cdata || StringEqual( p, startTag, false, encoding ) ) + { + cdata = true; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + if ( document ) + document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // Keep all the white space, ignore the encoding, etc. + while ( p && *p + && !StringEqual( p, endTag, false, encoding ) + ) + { + value += *p; + ++p; + } + + TIXML_STRING dummy; + p = ReadText( p, &dummy, false, endTag, false, encoding ); + return p; + } + else + { + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p && *p ) + return p-1; // don't truncate the '<' + return 0; + } +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) +{ + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for ( unsigned i=0; i +#include "setup.h" +#include "enum.h" + +namespace libxl { + + template struct ISheetT; + template struct IFormatT; + template struct IFontT; + + template + struct IBookT + { + virtual bool XLAPIENTRY load(const TCHAR* filename) = 0; + virtual bool XLAPIENTRY save(const TCHAR* filename) = 0; + + virtual bool XLAPIENTRY loadRaw(const char* data, unsigned size) = 0; + virtual bool XLAPIENTRY saveRaw(const char** data, unsigned* size) = 0; + + virtual ISheetT* XLAPIENTRY addSheet(const TCHAR* name, ISheetT* initSheet = 0) = 0; + virtual ISheetT* XLAPIENTRY insertSheet(int index, const TCHAR* name, ISheetT* initSheet = 0) = 0; + virtual ISheetT* XLAPIENTRY getSheet(int index) const = 0; + virtual SheetType XLAPIENTRY sheetType(int index) const = 0; + virtual bool XLAPIENTRY delSheet(int index) = 0; + virtual int XLAPIENTRY sheetCount() const = 0; + + virtual IFormatT* XLAPIENTRY addFormat(IFormatT* initFormat = 0) = 0; + virtual IFontT* XLAPIENTRY addFont(IFontT* initFont = 0) = 0; + virtual int XLAPIENTRY addCustomNumFormat(const TCHAR* customNumFormat) = 0; + virtual const TCHAR* XLAPIENTRY customNumFormat(int fmt) = 0; + + virtual IFormatT* XLAPIENTRY format(int index) = 0; + virtual int XLAPIENTRY formatSize() = 0; + + virtual IFontT* XLAPIENTRY font(int index) = 0; + virtual int XLAPIENTRY fontSize() = 0; + + virtual double XLAPIENTRY datePack(int year, int month, int day, int hour = 0, int min = 0, int sec = 0, int msec = 0) = 0; + virtual bool XLAPIENTRY dateUnpack(double value, int* year, int* month, int* day, int* hour = 0, int* min = 0, int* sec = 0, int* msec = 0) = 0; + + virtual Color XLAPIENTRY colorPack(int red, int green, int blue) = 0; + virtual void XLAPIENTRY colorUnpack(Color color, int* red, int* green, int* blue) = 0; + + virtual int XLAPIENTRY activeSheet() const = 0; + virtual void XLAPIENTRY setActiveSheet(int index) = 0; + + virtual int XLAPIENTRY pictureSize() const = 0; + virtual PictureType XLAPIENTRY getPicture(int index, const char** data, unsigned* size) const = 0; + + virtual int XLAPIENTRY addPicture(const TCHAR* filename) = 0; + virtual int XLAPIENTRY addPicture2(const char* data, unsigned size) = 0; + + virtual const TCHAR* XLAPIENTRY defaultFont(int* fontSize) = 0; + virtual void XLAPIENTRY setDefaultFont(const TCHAR* fontName, int fontSize) = 0; + + virtual bool XLAPIENTRY refR1C1() const = 0; + virtual void XLAPIENTRY setRefR1C1(bool refR1C1 = true) = 0; + + virtual void XLAPIENTRY setKey(const TCHAR* name, const TCHAR* key) = 0; + + virtual bool XLAPIENTRY rgbMode() = 0; + virtual void XLAPIENTRY setRgbMode(bool rgbMode = true) = 0; + + virtual int XLAPIENTRY version() const = 0; + virtual int XLAPIENTRY biffVersion() const = 0; + + virtual bool XLAPIENTRY isDate1904() const = 0; + virtual void XLAPIENTRY setDate1904(bool date1904 = true) = 0; + + virtual bool XLAPIENTRY isTemplate() const = 0; + virtual void XLAPIENTRY setTemplate(bool tmpl = true) = 0; + + virtual bool XLAPIENTRY setLocale(const char* locale) = 0; + virtual const char* XLAPIENTRY errorMessage() const = 0; + + virtual void XLAPIENTRY release() = 0; + + virtual ~IBookT() {} + }; + +} + +extern "C" XLAPI libxl::IBookT* XLAPIENTRY xlCreateBookA(); +extern "C" XLAPI libxl::IBookT* XLAPIENTRY xlCreateBookW(); + +extern "C" XLAPI libxl::IBookT* XLAPIENTRY xlCreateXMLBookA(); +extern "C" XLAPI libxl::IBookT* XLAPIENTRY xlCreateXMLBookW(); + +#endif diff --git a/OCI/include/IFontT.h b/OCI/include/IFontT.h new file mode 100644 index 0000000..2406bcd --- /dev/null +++ b/OCI/include/IFontT.h @@ -0,0 +1,41 @@ +#ifndef LIBXL_IFONTT_H +#define LIBXL_IFONTT_H + +#include "setup.h" +#include "enum.h" + +namespace libxl { + + template + struct IFontT + { + virtual int XLAPIENTRY size() const = 0; + virtual void XLAPIENTRY setSize(int size) = 0; + + virtual bool XLAPIENTRY italic() const = 0; + virtual void XLAPIENTRY setItalic(bool italic = true) = 0; + + virtual bool XLAPIENTRY strikeOut() const = 0; + virtual void XLAPIENTRY setStrikeOut(bool strikeOut = true) = 0; + + virtual Color XLAPIENTRY color() const = 0; + virtual void XLAPIENTRY setColor(Color color) = 0; + + virtual bool XLAPIENTRY bold() const = 0; + virtual void XLAPIENTRY setBold(bool bold = true) = 0; + + virtual Script XLAPIENTRY script() const = 0; + virtual void XLAPIENTRY setScript(Script script) = 0; + + virtual Underline XLAPIENTRY underline() const = 0; + virtual void XLAPIENTRY setUnderline(Underline underline) = 0; + + virtual const TCHAR* XLAPIENTRY name() const = 0; + virtual bool XLAPIENTRY setName(const TCHAR* name) = 0; + + virtual ~IFontT() {} + }; + +} + +#endif diff --git a/OCI/include/IFormatT.h b/OCI/include/IFormatT.h new file mode 100644 index 0000000..4f92bd1 --- /dev/null +++ b/OCI/include/IFormatT.h @@ -0,0 +1,94 @@ +#ifndef LIBXL_IFORMATT_H +#define LIBXL_IFORMATT_H + +#include "setup.h" +#include "enum.h" + +namespace libxl { + + template struct IFontT; + + template + struct IFormatT + { + virtual IFontT* XLAPIENTRY font() const = 0; + virtual bool XLAPIENTRY setFont(IFontT* font) = 0; + + virtual int XLAPIENTRY numFormat() const = 0; + virtual void XLAPIENTRY setNumFormat(int numFormat) = 0; + + virtual AlignH XLAPIENTRY alignH() const = 0; + virtual void XLAPIENTRY setAlignH(AlignH align) = 0; + + virtual AlignV XLAPIENTRY alignV() const = 0; + virtual void XLAPIENTRY setAlignV(AlignV align) = 0; + + virtual bool XLAPIENTRY wrap() const = 0; + virtual void XLAPIENTRY setWrap(bool wrap = true) = 0; + + virtual int XLAPIENTRY rotation() const = 0; + virtual bool XLAPIENTRY setRotation(int rotation) = 0; + + virtual int XLAPIENTRY indent() const = 0; + virtual void XLAPIENTRY setIndent(int indent) = 0; + + virtual bool XLAPIENTRY shrinkToFit() const = 0; + virtual void XLAPIENTRY setShrinkToFit(bool shrinkToFit = true) = 0; + + virtual void XLAPIENTRY setBorder(BorderStyle style = BORDERSTYLE_THIN) = 0; + virtual void XLAPIENTRY setBorderColor(Color color) = 0; + + virtual BorderStyle XLAPIENTRY borderLeft() const = 0; + virtual void XLAPIENTRY setBorderLeft(BorderStyle style = BORDERSTYLE_THIN) = 0; + + virtual BorderStyle XLAPIENTRY borderRight() const = 0; + virtual void XLAPIENTRY setBorderRight(BorderStyle style = BORDERSTYLE_THIN) = 0; + + virtual BorderStyle XLAPIENTRY borderTop() const = 0; + virtual void XLAPIENTRY setBorderTop(BorderStyle style = BORDERSTYLE_THIN) = 0; + + virtual BorderStyle XLAPIENTRY borderBottom() const = 0; + virtual void XLAPIENTRY setBorderBottom(BorderStyle style = BORDERSTYLE_THIN) = 0; + + virtual Color XLAPIENTRY borderLeftColor() const = 0; + virtual void XLAPIENTRY setBorderLeftColor(Color color) = 0; + + virtual Color XLAPIENTRY borderRightColor() const = 0; + virtual void XLAPIENTRY setBorderRightColor(Color color) = 0; + + virtual Color XLAPIENTRY borderTopColor() const = 0; + virtual void XLAPIENTRY setBorderTopColor(Color color) = 0; + + virtual Color XLAPIENTRY borderBottomColor() const = 0; + virtual void XLAPIENTRY setBorderBottomColor(Color color) = 0; + + virtual BorderDiagonal XLAPIENTRY borderDiagonal() const = 0; + virtual void XLAPIENTRY setBorderDiagonal(BorderDiagonal border) = 0; + + virtual BorderStyle XLAPIENTRY borderDiagonalStyle() const = 0; + virtual void XLAPIENTRY setBorderDiagonalStyle(BorderStyle style) = 0; + + virtual Color XLAPIENTRY borderDiagonalColor() const = 0; + virtual void XLAPIENTRY setBorderDiagonalColor(Color color) = 0; + + virtual FillPattern XLAPIENTRY fillPattern() const = 0; + virtual void XLAPIENTRY setFillPattern(FillPattern pattern) = 0; + + virtual Color XLAPIENTRY patternForegroundColor() const = 0; + virtual void XLAPIENTRY setPatternForegroundColor(Color color) = 0; + + virtual Color XLAPIENTRY patternBackgroundColor() const = 0; + virtual void XLAPIENTRY setPatternBackgroundColor(Color color) = 0; + + virtual bool XLAPIENTRY locked() const = 0; + virtual void XLAPIENTRY setLocked(bool locked = true) = 0; + + virtual bool XLAPIENTRY hidden() const = 0; + virtual void XLAPIENTRY setHidden(bool hidden = true) = 0; + + virtual ~IFormatT() {} + }; + +} + +#endif diff --git a/OCI/include/ISheetT.h b/OCI/include/ISheetT.h new file mode 100644 index 0000000..abfd06f --- /dev/null +++ b/OCI/include/ISheetT.h @@ -0,0 +1,203 @@ +#ifndef LIBXL_ISHEETT_H +#define LIBXL_ISHEETT_H + +#include "setup.h" +#include "enum.h" + +namespace libxl +{ + + template struct IFormatT; + + template + struct ISheetT + { + virtual CellType XLAPIENTRY cellType(int row, int col) const = 0; + virtual bool XLAPIENTRY isFormula(int row, int col) const = 0; + + virtual IFormatT* XLAPIENTRY cellFormat(int row, int col) const = 0; + virtual void XLAPIENTRY setCellFormat(int row, int col, IFormatT* format) = 0; + + virtual const TCHAR* XLAPIENTRY readStr(int row, int col, IFormatT** format = 0) = 0; + virtual bool XLAPIENTRY writeStr(int row, int col, const TCHAR* value, IFormatT* format = 0) = 0; + + virtual double XLAPIENTRY readNum(int row, int col, IFormatT** format = 0) const = 0; + virtual bool XLAPIENTRY writeNum(int row, int col, double value, IFormatT* format = 0) = 0; + + virtual bool XLAPIENTRY readBool(int row, int col, IFormatT** format = 0) const = 0; + virtual bool XLAPIENTRY writeBool(int row, int col, bool value, IFormatT* format = 0) = 0; + + virtual bool XLAPIENTRY readBlank(int row, int col, IFormatT** format) const = 0; + virtual bool XLAPIENTRY writeBlank(int row, int col, IFormatT* format) = 0; + + virtual const TCHAR* XLAPIENTRY readFormula(int row, int col, IFormatT** format = 0) = 0; + virtual bool XLAPIENTRY writeFormula(int row, int col, const TCHAR* value, IFormatT* format = 0) = 0; + + virtual const TCHAR* XLAPIENTRY readComment(int row, int col) const = 0; + virtual void XLAPIENTRY writeComment(int row, int col, const TCHAR* value, const TCHAR* author = 0, int width = 129, int height = 75) = 0; + + virtual bool XLAPIENTRY isDate(int row, int col) const = 0; + virtual ErrorType XLAPIENTRY readError(int row, int col) const = 0; + + virtual double XLAPIENTRY colWidth(int col) const = 0; + virtual double XLAPIENTRY rowHeight(int row) const = 0; + + virtual bool XLAPIENTRY setCol(int colFirst, int colLast, double width, IFormatT* format = 0, bool hidden = false) = 0; + virtual bool XLAPIENTRY setRow(int row, double height, IFormatT* format = 0, bool hidden = false) = 0; + + virtual bool XLAPIENTRY rowHidden(int row) const = 0; + virtual bool XLAPIENTRY setRowHidden(int row, bool hidden) = 0; + + virtual bool XLAPIENTRY colHidden(int col) const = 0; + virtual bool XLAPIENTRY setColHidden(int col, bool hidden) = 0; + + virtual bool XLAPIENTRY getMerge(int row, int col, int* rowFirst, int* rowLast, int* colFirst, int* colLast) = 0; + virtual bool XLAPIENTRY setMerge(int rowFirst, int rowLast, int colFirst, int colLast) = 0; + virtual bool XLAPIENTRY delMerge(int row, int col) = 0; + + virtual int XLAPIENTRY mergeSize() const = 0; + virtual bool XLAPIENTRY merge(int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast) = 0; + virtual bool XLAPIENTRY delMergeByIndex(int index) = 0; + + virtual int XLAPIENTRY pictureSize() const = 0; + virtual int XLAPIENTRY getPicture(int index, int* rowTop = 0, int* colLeft = 0, int* rowBottom = 0, int* colRight = 0, + int* width = 0, int* height = 0, int* offset_x = 0, int* offset_y = 0) const = 0; + + virtual void XLAPIENTRY setPicture(int row, int col, int pictureId, double scale = 1.0, int offset_x = 0, int offset_y = 0, Position pos = POSITION_MOVE_AND_SIZE) = 0; + virtual void XLAPIENTRY setPicture2(int row, int col, int pictureId, int width = -1, int height = -1, int offset_x = 0, int offset_y = 0, Position pos = POSITION_MOVE_AND_SIZE) = 0; + + virtual int XLAPIENTRY getHorPageBreak(int index) const = 0; + virtual int XLAPIENTRY getHorPageBreakSize() const = 0; + + virtual int XLAPIENTRY getVerPageBreak(int index) const = 0; + virtual int XLAPIENTRY getVerPageBreakSize() const = 0; + + virtual bool XLAPIENTRY setHorPageBreak(int row, bool pageBreak = true) = 0; + virtual bool XLAPIENTRY setVerPageBreak(int col, bool pageBreak = true) = 0; + + virtual void XLAPIENTRY split(int row, int col) = 0; + virtual bool XLAPIENTRY splitInfo(int* row, int* col) const = 0; + + virtual bool XLAPIENTRY groupRows(int rowFirst, int rowLast, bool collapsed = true) = 0; + virtual bool XLAPIENTRY groupCols(int colFirst, int colLast, bool collapsed = true) = 0; + + virtual bool XLAPIENTRY groupSummaryBelow() const = 0; + virtual void XLAPIENTRY setGroupSummaryBelow(bool below) = 0; + + virtual bool XLAPIENTRY groupSummaryRight() const = 0; + virtual void XLAPIENTRY setGroupSummaryRight(bool right) = 0; + + virtual bool XLAPIENTRY clear(int rowFirst = 0, int rowLast = 1048575, int colFirst = 0, int colLast = 16383) = 0; + + virtual bool XLAPIENTRY insertCol(int colFirst, int colLast) = 0; + virtual bool XLAPIENTRY insertRow(int rowFirst, int rowLast) = 0; + virtual bool XLAPIENTRY removeCol(int colFirst, int colLast) = 0; + virtual bool XLAPIENTRY removeRow(int rowFirst, int rowLast) = 0; + + virtual bool XLAPIENTRY copyCell(int rowSrc, int colSrc, int rowDst, int colDst) = 0; + + virtual int XLAPIENTRY firstRow() const = 0; + virtual int XLAPIENTRY lastRow() const = 0; + virtual int XLAPIENTRY firstCol() const = 0; + virtual int XLAPIENTRY lastCol() const = 0; + + virtual bool XLAPIENTRY displayGridlines() const = 0; + virtual void XLAPIENTRY setDisplayGridlines(bool show = true) = 0; + + virtual bool XLAPIENTRY printGridlines() const = 0; + virtual void XLAPIENTRY setPrintGridlines(bool print = true) = 0; + + virtual int XLAPIENTRY zoom() const = 0; + virtual void XLAPIENTRY setZoom(int zoom) = 0; + + virtual int XLAPIENTRY printZoom() const = 0; + virtual void XLAPIENTRY setPrintZoom(int zoom) = 0; + + virtual bool XLAPIENTRY getPrintFit(int* wPages, int* hPages) const = 0; + virtual void XLAPIENTRY setPrintFit(int wPages = 1, int hPages = 1) = 0; + + virtual bool XLAPIENTRY landscape() const = 0; + virtual void XLAPIENTRY setLandscape(bool landscape = true) = 0; + + virtual Paper XLAPIENTRY paper() const = 0; + virtual void XLAPIENTRY setPaper(Paper paper = PAPER_DEFAULT) = 0; + + virtual const TCHAR* XLAPIENTRY header() const = 0; + virtual bool XLAPIENTRY setHeader(const TCHAR* header, double margin = 0.5) = 0; + virtual double XLAPIENTRY headerMargin() const = 0; + + virtual const TCHAR* XLAPIENTRY footer() const = 0; + virtual bool XLAPIENTRY setFooter(const TCHAR* footer, double margin = 0.5) = 0; + virtual double XLAPIENTRY footerMargin() const = 0; + + virtual bool XLAPIENTRY hCenter() const = 0; + virtual void XLAPIENTRY setHCenter(bool hCenter = true) = 0; + + virtual bool XLAPIENTRY vCenter() const = 0; + virtual void XLAPIENTRY setVCenter(bool vCenter = true) = 0; + + virtual double XLAPIENTRY marginLeft() const = 0; + virtual void XLAPIENTRY setMarginLeft(double margin) = 0; + + virtual double XLAPIENTRY marginRight() const = 0; + virtual void XLAPIENTRY setMarginRight(double margin) = 0; + + virtual double XLAPIENTRY marginTop() const = 0; + virtual void XLAPIENTRY setMarginTop(double margin) = 0; + + virtual double XLAPIENTRY marginBottom() const = 0; + virtual void XLAPIENTRY setMarginBottom(double margin) = 0; + + virtual bool XLAPIENTRY printRowCol() const = 0; + virtual void XLAPIENTRY setPrintRowCol(bool print = true) = 0; + + virtual bool XLAPIENTRY printRepeatRows(int* rowFirst, int* rowLast) = 0; + virtual void XLAPIENTRY setPrintRepeatRows(int rowFirst, int rowLast) = 0; + + virtual bool XLAPIENTRY printRepeatCols(int* colFirst, int* colLast) = 0; + virtual void XLAPIENTRY setPrintRepeatCols(int colFirst, int colLast) = 0; + + virtual bool XLAPIENTRY printArea(int* rowFirst, int* rowLast, int* colFirst, int* colLast) = 0; + virtual void XLAPIENTRY setPrintArea(int rowFirst, int rowLast, int colFirst, int colLast) = 0; + + virtual void XLAPIENTRY clearPrintRepeats() = 0; + virtual void XLAPIENTRY clearPrintArea() = 0; + + virtual bool XLAPIENTRY getNamedRange(const TCHAR* name, int* rowFirst, int* rowLast, int* colFirst, int* colLast, int scopeId = SCOPE_UNDEFINED, bool* hidden = 0) = 0; + virtual bool XLAPIENTRY setNamedRange(const TCHAR* name, int rowFirst, int rowLast, int colFirst, int colLast, int scopeId = SCOPE_UNDEFINED) = 0; + virtual bool XLAPIENTRY delNamedRange(const TCHAR* name, int scopeId = SCOPE_UNDEFINED) = 0; + + virtual int XLAPIENTRY namedRangeSize() const = 0; + virtual const TCHAR* XLAPIENTRY namedRange(int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast, int* scopeId = 0, bool* hidden = 0) = 0; + + virtual int XLAPIENTRY hyperlinkSize() const = 0; + virtual const TCHAR* XLAPIENTRY hyperlink(int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast) = 0; + virtual bool XLAPIENTRY delHyperlink(int index) = 0; + virtual void XLAPIENTRY addHyperlink(const TCHAR* hyperlink, int rowFirst, int rowLast, int colFirst, int colLast) = 0; + + virtual const TCHAR* XLAPIENTRY name() const = 0; + virtual void XLAPIENTRY setName(const TCHAR* name) = 0; + + virtual bool XLAPIENTRY protect() const = 0; + virtual void XLAPIENTRY setProtect(bool protect = true) = 0; + + virtual SheetState XLAPIENTRY hidden() const = 0; + virtual bool XLAPIENTRY setHidden(SheetState state = SHEETSTATE_HIDDEN) = 0; + + virtual void XLAPIENTRY getTopLeftView(int* row, int* col) const = 0; + virtual void XLAPIENTRY setTopLeftView(int row, int col) = 0; + + virtual bool XLAPIENTRY rightToLeft() const = 0; + virtual void XLAPIENTRY setRightToLeft(bool rightToLeft = true) = 0; + + virtual void XLAPIENTRY setAutoFitArea(int rowFirst = 0, int colFirst = 0, int rowLast = -1, int colLast = -1) = 0; + + virtual void XLAPIENTRY addrToRowCol(const TCHAR* addr, int* row, int* col, bool* rowRelative = 0, bool* colRelative = 0) = 0; + virtual const TCHAR* XLAPIENTRY rowColToAddr(int row, int col, bool rowRelative = true, bool colRelative = true) = 0; + + virtual ~ISheetT() {} + }; + +} + +#endif diff --git a/OCI/include/libxl.h b/OCI/include/libxl.h new file mode 100644 index 0000000..b768f23 --- /dev/null +++ b/OCI/include/libxl.h @@ -0,0 +1,31 @@ +#ifndef LIBXL_CPP_H +#define LIBXL_CPP_H + +#define LIBXL_VERSION 0x03060500 + +#include "IBookT.h" +#include "ISheetT.h" +#include "IFormatT.h" +#include "IFontT.h" + +namespace libxl { + + #ifdef _UNICODE + typedef IBookT Book; + typedef ISheetT Sheet; + typedef IFormatT Format; + typedef IFontT Font; + #define xlCreateBook xlCreateBookW + #define xlCreateXMLBook xlCreateXMLBookW + #else + typedef IBookT Book; + typedef ISheetT Sheet; + typedef IFormatT Format; + typedef IFontT Font; + #define xlCreateBook xlCreateBookA + #define xlCreateXMLBook xlCreateXMLBookA + #endif + +} + +#endif diff --git a/OCI/include/nzerror.h b/OCI/include/nzerror.h new file mode 100644 index 0000000..2759aca --- /dev/null +++ b/OCI/include/nzerror.h @@ -0,0 +1,674 @@ +/* DISABLE check_long_lines */ + +/* + * $Header: security_src/public/nzerror.h /st_ldap_db11.2/1 2009/07/15 13:57:04 rchahal Exp $ + * + * Copyright (c) 1995, 2009, Oracle and/or its affiliates. + * All rights reserved. + */ + +/* ENABLE check_long_lines */ +/* + NAME + nzerror.h - error numbers for the Oracle Security Server + DESCRIPTION + None. + PUBLIC FUNCTION(S) + None. + PRIVATE FUNCTION(S) + None. + NOTES + A pragma is used to silence olint about the enum value names not being + unique within 7 characters. This limit is being changed to 30. + MODIFIED + rchahal 06/12/06 - + skalyana 01/30/05 - + rchahal 07/16/04 - add cert label + rchahal 07/06/04 - + rchahal 10/15/03 - bug 2513821 + rchahal 08/14/03 - new error range (43000 - 43499) + skalyana 08/25/03 - Error changes + rchahal 06/27/03 - RSA errors + rchahal 05/27/03 - convert wallet + skalyana 03/07/03 - Move FIPS errors + rchahal 02/28/03 - bug 2648177 + rchahal 01/20/03 - use sltsky + rchahal 11/11/02 - pkcs11 support + skalyana 11/29/02 - Add mutex errors + akoyfman 11/01/02 - adding crl cache + rchahal 10/23/02 - crldp error + rchahal 10/15/02 - fetch crl from ldap + rchahal 10/07/02 - crl support + akoyfman 10/16/02 - Update with SSL PLus 4.2 errors + skalyana 10/04/02 - Certicom SSL Plus 4.2 Upgrade changes + akoyfman 08/06/02 - adding sso wallet errors + akoyfman 07/12/02 - adding secret store errors + skalyana 07/07/02 - Add more errors for FIPS self tests + skalyana 07/01/02 - Add more errors + skalyana 06/03/02 - Add NZ error for self test failure. + ajacobs 02/22/01 - Add some entrust errors + vle 02/09/01 - add error mesg + lkethana 08/11/00 - Extension Errors + lkethana 07/30/00 - add pkcs12 errors + lkethana 06/17/00 - mult cert errors + lkethana 06/11/00 - multiple cert support + rturlapa 03/29/00 - Add error meesage for Entrust Login failure. + rwessman 07/07/99 - Deleted include of sslerrs.h. It caused the RDBMS bu + rwessman 07/02/99 - fixed merge errors + rwessman 07/01/99 - moved NZOS errors to nzerror to make them visible + supriya 12/16/98 - add new error for cert chain. + arswamin 12/04/98 - add NZERROR_NO_MATCHING_PRIVATE_KEY + qdinh 11/12/98 - add NZERROR_VALIDITY_EXPIRED. + arswamin 06/17/98 - add INIT_FAILED + sdange 06/10/98 - change wrong password to bad password + amthakur 06/09/98 - adding error messages + wliau 03/10/97 - Add new error message for snzdfo.c. + rwessman 03/14/97 - Consolidated PL/SQL toolkit errors into generic erro + rwessman 02/26/97 - Added NZERROR_UNSUPPORTED. Corrected values of + errors outside the valid range. + asriniva 03/02/97 - Fix olint warning + rwessman 02/26/97 - Added NZERROR_UNSUPPORTED + rwessman 01/02/97 - Changed PLSQL package errors to be TK_PLSQL to + separate them from the errors generated by the + Oracle interface. + rwessman 12/30/96 - Merged in PL/SQL toolkit errors + sdange 11/14/96 - (Added NZERROR_DECRYPT_FAILED to the enum list) + rwessman 12/02/96 - + rwessman 11/25/96 - Added error messages for PL/SQL functions. + asriniva 10/31/96 - Include oratypes.h + asriniva 10/29/96 - Fix numbering. + asriniva 10/29/96 - Fix error numbers + asriniva 10/29/96 - Correct type-o + asriniva 10/28/96 - Add more TK errors + asriniva 10/28/96 - Convert OKAPI errors to TK errors. + rwessman 10/17/96 - still more OSS TK errors + asriniva 10/16/96 - OKAPI errors + asriniva 10/15/96 - OSSTK errors + rwessman 10/15/96 - Added more OSS TK errors + asriniva 10/09/96 - Add OSSTK errors. + rwessman 09/05/96 - Added errors for PL/SQL functions. + wliau 09/05/96 - correct error numbers. + $Log: $ + * Revision 1.26 1996/07/15 23:07:23 wliau + * Added NZERROR_AUTH_SHARED_MEMORY + * + * Revision 1.25 1996/07/01 20:40:15 asriniva + * Finished RSA verify/sign. + * + * Revision 1.24 1996/06/27 20:39:41 rwessman + * Added more errors. + * + * Revision 1.23 1996/05/31 17:33:40 rwessman + * Updated nzerror.h to contain bug # for olint enum bug. + * + * Revision 1.22 1996/05/31 17:12:30 rwessman + * Assigned values to the various errors. + * + * Revision 1.21 1996/05/13 20:46:58 ggilchri + * Added more attribute related error conditions + * +*/ + +#ifndef NZERROR_ORACLE +# define NZERROR_ORACLE + +#ifndef ORATYPES +# include +#endif /* ORATYPES */ + +/* +** Errors - when an error is added here, a message corresponding to the +** error number must be added to the message file. +** New errors must be assigned numbers, otherwise the compiler can assign any +** value that it wants, which may lead to invalid error numbers being +** generated. +** The number range currently assigned to the OSS is 28750 - 29249 +** New number range 43000 - 43499 +*/ + +typedef enum nzerror +{ + NZERROR_OK = 0, + NZERROR_GENERIC = 28750, /* A catchall for errors */ + NZERROR_NO_MEMORY = 28751, /* No more memory */ + NZERROR_DATA_SOURCE_INIT_FAILED = 28752, /* Failed to init data source */ + NZERROR_DATA_SOURCE_TERM_FAILED = 28753,/* Failed to terminate data source */ + NZERROR_OBJECT_STORE_FAILED = 28754, /* Store object in data source failed */ + NZERROR_OBJECT_GET_FAILED = 28755, + /* Failed to obtain object from data source */ + NZERROR_MEMORY_ALLOC_FAILED = 28756, + /* Callback failed to allocate memory */ + NZERROR_MEMORY_ALLOC_0_BYTES = 28757, + /* Attempted to ask for 0 bytes of memory */ + NZERROR_MEMORY_FREE_FAILED = 28758, + /* Callback failed to free memory */ + NZERROR_FILE_OPEN_FAILED = 28759, + /* Open of file failed */ + NZERROR_LIST_CREATION_FAILED = 28760, + /* Creation of list failed */ + NZERROR_NO_ELEMENT = 28761, + /* No list element found */ + NZERROR_ELEMENT_ADD_FAILED = 28762, + /* Addition of list element failed */ + NZERROR_PARAMETER_BAD_TYPE = 28763, + /* Retrieval of an unknown parameter type */ + NZERROR_PARAMETER_RETRIEVAL = 28764, /* Retrieval of parameter failed */ + + NZERROR_NO_LIST = 28765, /* Data method list does not exist */ + NZERROR_TERMINATE_FAIL = 28766, /* Failed to terminate */ + NZERROR_BAD_VERSION_NUMBER = 28767, /* Bad version number */ + NZERROR_BAD_MAGIC_NUMBER = 28768, /* Bad magic number */ + NZERROR_METHOD_NOT_FOUND = 28769, + /* Data retrieval method specified does not exist */ + NZERROR_ALREADY_INITIALIZED = 28770, + /*The data source is already initialized */ + NZERROR_NOT_INITIALIZED = 28771, /* The data source is not initialized */ + NZERROR_BAD_FILE_ID = 28772, /* File ID is bad */ + NZERROR_WRITE_MAGIC_VERSION = 28773, /* Failed to write magic and version */ + NZERROR_FILE_WRITE_FAILED = 28774, /* Failed to write to file */ + NZERROR_FILE_CLOSE_FAILED = 28775, /* Failed to close file */ + NZERROR_OUTPUT_BUFFER_TOO_SMALL = 28776, + /* The buffer supplied by the caller is too small */ + NZERROR_BINDING_CREATION_FAILED = 28777,/* NL failed in creating a binding */ + NZERROR_PARAMETER_MALFORMED = 28778, /* A parameter was in a bad format */ + NZERROR_PARAMETER_NO_METHOD = 28779, + /* No method was specified for a data type */ + NZERROR_BAD_PARAMETER_METHOD = 28780, /* Illegal method for data type */ + NZERROR_PARAMETER_NO_DATA = 28781, /* No method specified when required */ + NZERROR_NOT_ALLOCATED = 28782, /* Data source is not allocated */ + NZERROR_INVALID_PARAMETER = 28783, /* Invalid parameter name */ + NZERROR_FILE_NAME_TRANSLATION = 28784,/* Could not translate OSD file name */ + NZERROR_NO_SUCH_PARAMETER = 28785, /* Selected parameter is non-existent */ + + NZERROR_DECRYPT_FAILED = 28786, + /* Encrypted private key decryption failure */ + NZERROR_ENCRYPT_FAILED = 28787, /* Private key encryption failed */ + + NZERROR_INVALID_INPUT = 28788, /* Incorrect input or unknown error */ + + NZERROR_NAME_TYPE_NOT_FOUND = 28789, + /* Type of name requested is not available */ + NZERROR_NLS_STRING_OPEN_FAILED = 28790, + /* Failure to generate an NLS string */ + NZERROR_CERTIFICATE_VERIFY = 28791, /* Failed to verify a certificate */ + NZERROR_OCI_PLSQL_FAILED = 28792, + /* an OCI call to process some plsql failed */ + NZERROR_OCI_BIND_FAILED = 28793, + /* an OCI call to bind an internal var. failed */ + NZERROR_ATTRIBUTE_INIT = 28794, /* failed to init role retrieval */ + NZERROR_ATTRIBUTE_FINISH_FAILED = 28795,/* Did not complete role retrieval */ + NZERROR_UNSUPPORTED_METHOD = 28796, /* Data method specified not supported */ + NZERROR_INVALID_KEY_DATA_TYPE = 28797, + /* Invalid data type specified for key */ + NZEROR_BIND_SUBKEY_COUNT = 28798, + /* Number of sub-keys to bind does not match count in initialized key */ + NZERROR_AUTH_SHARED_MEMORY = 28799, + /* Failed to retreieve authentication information from the shared memory */ + NZERROR_RIO_OPEN = 28800, /* RIO Open Failed */ + NZERROR_RIO_OBJECT_TYPE = 28801, /* RIO object type invalid */ + NZERROR_RIO_MODE = 28802, /* RIO mode invalid */ + NZERROR_RIO_IO = 28803, /* RIO io set or numberinvalid */ + NZERROR_RIO_CLOSE = 28804, /* RIO close failed */ + NZERROR_RIO_RETRIEVE = 28805, /* RIO retrieve failed */ + NZERROR_RIO_STORE = 28806, /* RIO store failed */ + NZERROR_RIO_UPDATE = 28807, /* RIO update failed */ + NZERROR_RIO_INFO = 28808, /* RIO info failed */ + NZERROR_RIO_DELETE = 28809, /* RIO delete failed */ + NZERROR_KD_CREATE = 28810, /* Key descriptor create failed */ + NZERROR_RIO_ACCESS_DESCRIPTOR = 28811, /* access descriptor invalid */ + NZERROR_RIO_RECORD = 28812, /* record invalid */ + NZERROR_RIO_RECORD_TYPE = 28813, /* record type and AD type not matched */ + NZERROR_PLSQL_ORACLE_TO_REAL = 28814, + /* A number passed to PL/SQL could not be converted to real format */ + NZERROR_PLSQL_REAL_TO_ORACLE = 28815, + /* A number in machine format could not be converted to Oracle format */ + NZERROR_TK_PLSQL_NO_PASSWORD = 28816, + /* A password was not provided to a PL/SQL function */ + NZERROR_TK_PLSQL_GENERIC = 28817, + /* A PL/SQL function returned an error */ + NZERROR_TK_PLSQL_NO_CONTEXT = 28818, + /* The package context was not specified to a PL/SQL function */ + NZERROR_TK_PLSQL_NO_DIST_NAME = 28819, + /* The user's distinguished name was not provided to a PL/SQL function */ + NZERROR_TK_PLSQL_NO_STATE = 28820, +/* The state of either a signature or decryption/encryption was not provided */ + NZERROR_TK_PLSQL_NO_INPUT = 28821, + /* An input buffer was specified to a PL/SQL function */ + NZERROR_TK_PLSQL_NO_SEED = 28822, + /* No seed was specified to the PL/SQL seed initialization function */ + NZERROR_TK_PLSQL_NO_BYTES = 28823, + /* Number of bytes was not specified to the PL/SQL random number generator */ + NZERROR_TK_INVALID_STATE = 28824, + /* Invalid encryption/decryption/signature state passed */ + NZERROR_TK_PLSQL_NO_ENG_FUNC = 28825, + /* No crypto engine function was passed in */ + NZERROR_TK_INV_ENG_FUNC = 28826, + /* An invalid crypto engine function was passed in */ + NZERROR_TK_INV_CIPHR_TYPE = 28827, + /* An invalid cipher type was passed in */ + NZERROR_TK_INV_IDENT_TYPE = 28828, + /* An invalid identity type was specified */ + NZERROR_TK_PLSQL_NO_CIPHER_TYPE = 28829, + /* No cipher type was specified */ + NZERROR_TK_PLSQL_NO_IDENT_TYPE = 28830, + /* No identity type was specified */ + NZERROR_TK_PLSQL_NO_DATA_FMT = 28831, + /* No data unit format was specified */ + NZERROR_TK_INV_DATA_FMT = 28832, + /* Invalid data unit format was provided to function */ + NZERROR_TK_PLSQL_INSUFF_INFO = 28833, + /* Not enough info (usually parameters) provided to a PL/SQL function */ + NZERROR_TK_PLSQL_BUF_TOO_SMALL = 28834, + /* Buffer provided by PL/SQL is too small for data to be returned */ + NZERROR_TK_PLSQL_INV_IDENT_DESC = 28835, + /* Identity descriptor not present or too small */ + NZERROR_TK_PLSQL_WALLET_NOTOPEN = 28836, + /* Wallet has not been opened yet */ + NZERROR_TK_PLSQL_NO_WALLET = 28837, + /* No wallet descriptor specified to PL/SQL function */ + NZERROR_TK_PLSQL_NO_IDENTITY = 28838, + /* No identity descriptor specified to PL/SQL function */ + NZERROR_TK_PLSQL_NO_PERSONA = 28839, + /* No persona descriptor was specified to PL/SQL function */ + NZERROR_TK_PLSQL_WALLET_OPEN = 28840, + /* Wallet was already opened */ + NZERROR_UNSUPPORTED = 28841, /* Operation is not supported */ + NZERROR_FILE_BAD_PERMISSION = 28842, /* Bad file permission specified */ + NZERROR_FILE_OSD_ERROR = 28843, /* OSD error when opening file */ + NZERROR_NO_WALLET = 28844, /* cert + privkey + tp files do not exist */ + NZERROR_NO_CERTIFICATE_ALERT = 28845, /* no certificate */ + NZERROR_NO_PRIVATE_KEY = 28846, /* no private-key */ + NZERROR_NO_CLEAR_PRIVATE_KEY_FILE = 28847, /* no clear key-file */ + NZERROR_NO_ENCRYPTED_PRIVATE_KEY_FILE = 28848, /* no encrypted priv key */ + NZERROR_NO_TRUSTPOINTS = 28849, /* no trustpoints */ + NZERROR_NO_CLEAR_TRUSTPOINT_FILE = 28850, /* no clear trustpoints */ + NZERROR_NO_ENCRYPTED_TRUSTPOINT_FILE = 28851, /* no encrypted trustpoints */ + NZERROR_BAD_PASSWORD = 28852, /* bad password */ + NZERROR_INITIALIZATION_FAILED = 28853, /* init failed or + module loading failed */ + /******************************* SSL ERRORS ********************************/ + /* + * In order to allow SSL errors to be mapped to Oracle errors, space is + * provided here. One Oracle error is provided for each SSL error to make + * error handling easier. A macro is provided to do the conversion. + * NOTE: ANY CHANGE IN SSL ERRORS MUST BE REFLECTED HERE. + * To add an SSL error, use the following formula to calculate the Oracle + * error: + * new_oracle_error = (new_ssl_error - SSLMemoryError) + NZERROR_SSLMemoryErr + * or numerically: + * new_oracle_error = (new_ssl_error - -7000) + 28854 + */ + NZERROR_SSLMemoryErr = 28854, + NZERROR_SSLUnsupportedErr = 28855, + NZERROR_SSLOverflowErr = 28856, + NZERROR_SSLUnknownErr = 28857, + NZERROR_SSLProtocolErr = 28858, + NZERROR_SSLNegotiationErr = 28859, + NZERROR_SSLFatalAlert = 28860, + NZERROR_SSLWouldBlockErr = 28861, + NZERROR_SSLIOErr = 28862, + NZERROR_SSLSessionNotFoundErr = 28863, + NZERROR_SSLConnectionClosedGraceful = 28864, + NZERROR_SSLConnectionClosedError = 28865, + NZERROR_ASNBadEncodingErr = 28866, + NZERROR_ASNIntegerTooBigErr = 28867, + NZERROR_X509CertChainInvalidErr = 28868, + NZERROR_X509CertExpiredErr = 28869, + NZERROR_X509NamesNotEqualErr = 28870, + NZERROR_X509CertChainIncompleteErr = 28871, + NZERROR_X509DataNotFoundErr = 28872, + NZERROR_SSLBadParameterErr = 28873, + NZERROR_SSLIOClosedOverrideGoodbyeKiss = 28874, + NZERROR_X509MozillaSGCErr = 28875, + NZERROR_X509IESGCErr = 28876, + NZERROR_ImproperServerCredentials = 28877, + NZERROR_ImproperClientCredentials = 28878, + NZERROR_NoProtocolSideSet = 28879, + NZERROR_setPersonaFailed = 28880, + NZERROR_setCertFailed = 28881, + NZERROR_setVKeyFailed = 28882, + NZERROR_setTPFailed = 28883, + NZERROR_BadCipherSuite = 28884, + NZERROR_NoKeyPairForKeyUsage = 28885, + +/* ============>>> ENTRUST ERRORS */ + NZERROR_EntrustLoginFailed = 28890, + NZERROR_EntrustGetInfoFailed = 28891, + NZERROR_EntrustLoadCertificateFailed = 28892, + NZERROR_EntrustGetNameFailed = 28893, + +/* ============>>> NZERRORS CONTINUED */ + NZERROR_CertNotInstalled = 29000, + NZERROR_ServerDNMisMatched = 29002, + NZERROR_ServerDNMisConfigured = 29003, + +/* ============>>> PKI VENDORS ERRORS 29050 - 29099 */ + +/* ============>>> SSL Errors CONTINUED */ + NZERROR_CIC_ERR_SSL_ALERT_CB_FAILURE = 29004, + NZERROR_CIC_ERR_SSL_BAD_CERTIFICATE = 29005, + NZERROR_CIC_ERR_SSL_BAD_CERTIFICATE_REQUEST = 29006, + NZERROR_CIC_ERR_SSL_BAD_CLEAR_KEY_LEN = 29007, + NZERROR_CIC_ERR_SSL_BAD_DHPARAM_KEY_LENGTH = 29008, + NZERROR_CIC_ERR_SSL_BAD_ENCRYPTED_KEY_LEN = 29009, + NZERROR_CIC_ERR_SSL_BAD_EXPORT_KEY_LENGTH = 29010, + NZERROR_CIC_ERR_SSL_BAD_FINISHED_MESSAGE = 29011, + NZERROR_CIC_ERR_SSL_BAD_KEY_ARG_LEN = 29012, + NZERROR_CIC_ERR_SSL_BAD_MAC = 29013, + NZERROR_CIC_ERR_SSL_BAD_MAX_FRAGMENT_LENGTH_EXTENSION = 29014, + NZERROR_CIC_ERR_SSL_BAD_MESSAGE_LENGTH = 29015, + NZERROR_CIC_ERR_SSL_BAD_PKCS1_PADDING = 29016, + NZERROR_CIC_ERR_SSL_BAD_PREMASTER_SECRET_LENGTH = 29017, + NZERROR_CIC_ERR_SSL_BAD_PREMASTER_SECRET_VERSION = 29018, + NZERROR_CIC_ERR_SSL_BAD_PROTOCOL_VERSION = 29019, + NZERROR_CIC_ERR_SSL_BAD_RECORD_LENGTH = 29020, + NZERROR_CIC_ERR_SSL_BAD_SECRET_KEY_LEN = 29021, + NZERROR_CIC_ERR_SSL_BAD_SIDE = 29022, + NZERROR_CIC_ERR_SSL_BUFFERS_NOT_EMPTY = 29023, + NZERROR_CIC_ERR_SSL_CERTIFICATE_VALIDATE_FAILED = 29024, + NZERROR_CIC_ERR_SSL_CERT_CHECK_CALLBACK = 29025, + NZERROR_CIC_ERR_SSL_DECRYPT_FAILED = 29026, + NZERROR_CIC_ERR_SSL_ENTROPY_COLLECTION = 29027, + NZERROR_CIC_ERR_SSL_FAIL_SERVER_VERIFY = 29028, + NZERROR_CIC_ERR_SSL_HANDSHAKE_ALREADY_COMPLETED = 29029, + NZERROR_CIC_ERR_SSL_HANDSHAKE_REQUESTED = 29030, + NZERROR_CIC_ERR_SSL_HANDSHAKE_REQUIRED = 29031, + NZERROR_CIC_ERR_SSL_INCOMPLETE_IDENTITY = 29032, + NZERROR_CIC_ERR_SSL_INVALID_PFX = 29033, + NZERROR_CIC_ERR_SSL_NEEDS_CIPHER_OR_CLIENTAUTH = 29034, + NZERROR_CIC_ERR_SSL_NEEDS_PRNG = 29035, + NZERROR_CIC_ERR_SSL_NOT_SUPPORTED = 29036, + NZERROR_CIC_ERR_SSL_NO_CERTIFICATE = 29037, + NZERROR_CIC_ERR_SSL_NO_MATCHING_CERTIFICATES = 29038, + NZERROR_CIC_ERR_SSL_NO_MATCHING_CIPHER_SUITES = 29039, + NZERROR_CIC_ERR_SSL_NO_SUPPORTED_CIPHER_SUITES = 29040, + NZERROR_CIC_ERR_SSL_NULL_CB = 29041, + NZERROR_CIC_ERR_SSL_READ_BUFFER_NOT_EMPTY = 29042, + NZERROR_CIC_ERR_SSL_READ_REQUIRED = 29043, + NZERROR_CIC_ERR_SSL_RENEGOTIATION_ALREADY_REQUESTED = 29044, + NZERROR_CIC_ERR_SSL_RENEGOTIATION_REFUSED = 29045, + NZERROR_CIC_ERR_SSL_RESUMABLE_SESSION = 29046, + NZERROR_CIC_ERR_SSL_TLS_EXTENSION_MISMATCH = 29047, + NZERROR_CIC_ERR_SSL_UNEXPECTED_MSG = 29048, + NZERROR_CIC_ERR_SSL_UNKNOWN_RECORD = 29049, + NZERROR_CIC_ERR_SSL_UNSUPPORTED_CLIENT_AUTH_MODE = 29050, + NZERROR_CIC_ERR_SSL_UNSUPPORTED_PUBKEY_TYPE = 29051, + NZERROR_CIC_ERR_SSL_WRITE_BUFFER_NOT_EMPTY = 29052, + NZERROR_CIC_ERR_PKCS12_MISSING_ALG = 29053, + NZERROR_CIC_ERR_PKCS_AUTH_FAILED = 29054, + NZERROR_CIC_ERR_PKCS_BAD_CONTENT_TYPE = 29055, + NZERROR_CIC_ERR_PKCS_BAD_INPUT = 29056, + NZERROR_CIC_ERR_PKCS_BAD_PADDING = 29057, + NZERROR_CIC_ERR_PKCS_BAD_SN = 29058, + NZERROR_CIC_ERR_PKCS_BAD_SN_LENGTH = 29059, + NZERROR_CIC_ERR_PKCS_BAD_VERSION = 29060, + NZERROR_CIC_ERR_PKCS_BASE = 29061, + NZERROR_CIC_ERR_PKCS_FIELD_NOT_PRESENT = 29062, + NZERROR_CIC_ERR_PKCS_NEED_CERTVAL = 29063, + NZERROR_CIC_ERR_PKCS_NEED_PASSWORD = 29064, + NZERROR_CIC_ERR_PKCS_NEED_PKC = 29065, + NZERROR_CIC_ERR_PKCS_NEED_PRV_KEY = 29066, + NZERROR_CIC_ERR_PKCS_NEED_TRUSTED = 29067, + NZERROR_CIC_ERR_PKCS_UNSUPPORTED_CERT_FORMAT = 29068, + NZERROR_CIC_ERR_PKCS_UNSUP_PRVKEY_TYPE = 29069, + NZERROR_CIC_ERR_CODING_BAD_PEM = 29070, + NZERROR_CIC_ERR_CODING_BASE = 29071, + NZERROR_CIC_ERR_DER_BAD_ENCODING = 29072, + NZERROR_CIC_ERR_DER_BAD_ENCODING_LENGTH = 29073, + NZERROR_CIC_ERR_DER_BASE = 29074, + NZERROR_CIC_ERR_DER_ELEMENT_TOO_LONG = 29075, + NZERROR_CIC_ERR_DER_INDEFINITE_LENGTH = 29076, + NZERROR_CIC_ERR_DER_NO_MORE_ELEMENTS = 29077, + NZERROR_CIC_ERR_DER_OBJECT_TOO_LONG = 29078, + NZERROR_CIC_ERR_DER_TAG_SIZE = 29079, + NZERROR_CIC_ERR_DER_TIME_OUT_OF_RANGE = 29080, + NZERROR_CIC_ERR_DER_UNUSED_BITS_IN_BIT_STR = 29081, + NZERROR_CIC_ERR_GENERAL_BASE = 29082, + NZERROR_CIC_ERR_HASH_BASE = 29083, + NZERROR_CIC_ERR_ILLEGAL_PARAM = 29084, + NZERROR_CIC_ERR_MEM_NOT_OURS = 29085, + NZERROR_CIC_ERR_MEM_OVERRUN = 29086, + NZERROR_CIC_ERR_MEM_UNDERRUN = 29087, + NZERROR_CIC_ERR_MEM_WAS_FREED = 29088, + NZERROR_CIC_ERR_NOT_FOUND = 29090, + NZERROR_CIC_ERR_NO_PTR = 29091, + NZERROR_CIC_ERR_TIMEOUT = 29092, + NZERROR_CIC_ERR_UNIT_MASK = 29093, + NZERROR_CIC_ERR_BAD_CTX = 29094, + NZERROR_CIC_ERR_BAD_INDEX = 29095, + NZERROR_CIC_ERR_BAD_LENGTH = 29096, + NZERROR_CIC_ERR_CODING_BAD_ENCODING = 29097, + NZERROR_CIC_ERR_SSL_NO_CLIENT_AUTH_MODES = 29098, + + /* ============>>> PKCS12 error 29100 - 29149 */ + + NZERROR_LOCKEYID_CREATE_FAILED = 29100, + NZERROR_P12_ADD_PVTKEY_FAILED = 29101, + NZERROR_P12_ADD_CERT_FAILED = 29102, + NZERROR_P12_WLT_CREATE_FAILED = 29103, + NZERROR_P12_ADD_CERTREQ_FAILED = 29104, + NZERROR_P12_WLT_EXP_FAILED = 29105, + NZERROR_P12_WLT_IMP_FAILED = 29106, + NZERROR_P12_CREATE_FAILED = 29107, + NZERROR_P12_DEST_FAILED = 29107, + NZERROR_P12_RAND_ERROR = 29108, + NZERROR_P12_PVTKEY_CRT_FAILED = 29109, + NZERROR_P12_INVALID_BAG = 29110, + NZERROR_P12_INVALID_INDEX = 29111, + NZERROR_P12_GET_CERT_FAILED = 29112, + NZERROR_P12_GET_PVTKEY_FAILED = 29113, + NZERROR_P12_IMP_PVTKEY_FAILED = 29114, + NZERROR_P12_EXP_PVTKEY_FAILED = 29115, + NZERROR_P12_GET_ATTRIB_FAILED = 29116, + NZERROR_P12_ADD_ATTRIB_FAILED = 29117, + NZERROR_P12_CRT_ATTRIB_FAILED = 29118, + NZERROR_P12_IMP_CERT_FAILED = 29119, + NZERROR_P12_EXP_CERT_FAILED = 29120, + NZERROR_P12_ADD_SECRET_FAILED = 29121, + NZERROR_P12_ADD_PKCS11INFO_FAILED = 29122, + NZERROR_P12_GET_PKCS11INFO_FAILED = 29123, + NZERROR_P12_MULTIPLE_PKCS11_LIBNAME = 29124, + NZERROR_P12_MULTIPLE_PKCS11_TOKENLABEL = 29125, + NZERROR_P12_MULTIPLE_PKCS11_TOKENPASSPHRASE = 29126, + NZERROR_P12_UNKNOWN_PKCS11INFO = 29127, + NZERROR_P12_PKCS11_LIBNAME_NOT_SET = 29128, + NZERROR_P12_PKCS11_TOKENLABEL_NOT_SET = 29129, + NZERROR_P12_PKCS11_TOKENPASSPHRASE_NOT_SET = 29130, + NZERROR_P12_MULTIPLE_PKCS11_CERTLABEL = 29131, + +/* ===========>>> SSL Errors CONTINUED 29135 - 29139 */ + NZERROR_CIC_ERR_RANDOM = 29135, + NZERROR_CIC_ERR_SMALL_BUFFER = 29136, + NZERROR_CIC_ERR_SSL_BAD_CONTEXT = 29137, + +/* ==========>>> Mutex Errors 29138 - 29139 */ + NZERROR_MUTEX_INITIALIZE_FAILED = 29138, + NZERROR_MUTEX_DESTROY_FAILED = 29139, + + +/* ============>>> EXTENSIONS Errors 29140 - 29149 */ + NZERROR_BS_CERTOBJ_CREAT_FAILED = 29140, + NZERROR_BS_DER_IMP_FAILED = 29141, + + +/* ============>>> FIPS ERRORS 29150 - 29175 */ + NZERROR_DES_SELF_TEST_FAILED = 29150, + NZERROR_3DES_SELF_TEST_FAILED = 29151, + NZERROR_SHA_SELF_TEST_FAILED = 29152, + NZERROR_RSA_SELF_TEST_FAILED = 29153, + NZERROR_DRNG_SELF_TEST_FAILED = 29154, + NZERROR_CKEYPAIR_SELF_TEST_FAILED = 29155, + NZERROR_CRNG_SELF_TEST_FAILED = 29156, + NZERROR_FIPS_PATHNAME_ERROR = 29157, + NZERROR_FIPS_LIB_OPEN_FAILED = 29158, + NZERROR_FIPS_LIB_READ_ERROR = 29159, + NZERROR_FIPS_LIB_DIFFERS = 29160, + NZERROR_DAC_SELF_TEST_FAILED = 29161, + NZERROR_NONFIPS_CIPHERSUITE = 29162, + NZERROR_VENDOR_NOT_SUPPORTED_FIPS_MODE = 29163, + NZERROR_EXTERNAL_PKCS12_NOT_SUPPORTED_FIPS_MODE = 29164, + NZERROR_AES_SELF_TEST_FAILED = 29165, + +/* ============>>> CRL ERRORS 29176 - 29200 */ + NZERROR_CRL_SIG_VERIFY_FAILED = 29176, /*CRL signature verification failed*/ + NZERROR_CERT_NOT_IN_CRL = 29177, + /*Cert is not in CRL - cert is not revoked*/ + NZERROR_CERT_IN_CRL = 29178, /*Cert is in CRL - cert is revoked*/ + NZERROR_CERT_IN_CRL_CHECK_FAILED = 29179, /*Cert revocation check failed */ + NZERROR_INVALID_CERT_STATUS_PROTOCOL = 29180, + NZERROR_LDAP_OPEN_FAILED = 29181, /* ldap_open failed */ + NZERROR_LDAP_BIND_FAILED = 29182, /* ldap_bind failed */ + NZERROR_LDAP_SEARCH_FAILED = 29183, /* ldap_search failed */ + NZERROR_LDAP_RESULT_FAILED = 29184, /* ldap_result failed */ + NZERROR_LDAP_FIRSTATTR_FAILED = 29185, /* ldap_first_attribute failed */ + NZERROR_LDAP_GETVALUESLEN_FAILED = 29186, /* ldap_get_values_len failed */ + NZERROR_LDAP_UNSUPPORTED_VALMEC = 29187, + /* unsupported validation mechanism */ + NZERROR_LDAP_COUNT_ENTRIES_FAILED = 29188,/* ldap_count_entries failed */ + NZERROR_LDAP_NO_ENTRY_FOUND = 29189, /* No entry found in OID */ + NZERROR_LDAP_MULTIPLE_ENTRIES_FOUND = 29190, /* Multiple entries in OID*/ + NZERROR_OID_INFO_NOT_SET = 29191, + NZERROR_LDAP_VALMEC_NOT_SET = 29192, + /* Validation mechanism not set in OID*/ + NZERROR_CRLDP_NO_CRL_FOUND = 29193, + /* No CRL found using CRLDP mechanism */ + NZERROR_CRL_NOT_IN_CACHE = 29194, /* No CRL found in the cache*/ + NZERROR_CRL_EXPIRED = 29195, /* CRL nextUpdate time is in the past */ + +/* ============>>> ADD ERRORS HERE -- NOTE DECREASING numbers */ + NZERROR_DN_MATCH = 29222, /* for nztCompareDN */ + NZERROR_CERT_CHAIN_CREATION = 29223, /* unable to create a cert chain + * with the existing TPs for the + * cert to be installed. + */ + NZERROR_NO_MATCHING_CERT_REQ = 29224, /* No matching cert_req was + * found the corresponding to + * the privatekey which + * matches the cert to be + * installed */ + NZERROR_CERT_ALREADY_INSTALLED = 29225, /* we are attempting to + * install a cert again into + * a persona which already + * has it installed. + */ + NZERROR_NO_MATCHING_PRIVATE_KEY = 29226, /* could not find a matching + * persona-private(privatekey) in + * the Persona, for the given + * cert(public key). + */ + NZERROR_VALIDITY_EXPIRED = 29227, /* certificate validity date expired */ + NZERROR_TK_BYTES_NEEDED = 29228, /* Couldn't determine # of bytes needed */ + NZERROR_TK_BAD_MAGIC_NUMBER = 29229, + /* Magic number found in header does not match expected */ + NZERROR_TK_BAD_HEADER_LENGTH = 29230, + /* Header length passed in not sufficient for message header */ + NZERROR_TK_CE_INIT = 29231, /* Crypto engine failed to initialize */ + NZERROR_TK_CE_KEYINIT = 29232, /* Crypto engine key initialization failed */ + NZERROR_TK_CE_ENCODE_KEY = 29233, /* Count not encode key object */ + NZERROR_TK_CE_DECODE_KEY = 29234, /* Could not decode key into object */ + NZERROR_TK_CE_GEYKEYINFO = 29235, /* Crypto engine failed to get key info */ + NZERROR_TK_SEED_RANDOM = 29236, /* Couldn't seed random number generator */ + NZERROR_TK_CE_ALGFINISH = 29237, /* Couldn't finish algorithm */ + NZERROR_TK_CE_ALGAPPLY = 29238, /* Couldn't apply algorithm to data */ + NZERROR_TK_CE_ALGINIT = 29239, /* Couldn't init CE for algorithm */ + NZERROR_TK_ALGORITHM = 29240, /* Have no idea what algorithm you want */ + NZERROR_TK_CANNOT_GROW = 29241, /* Cannot grow output buffer block */ + NZERROR_TK_KEYSIZE = 29242, /* Key not large enough for data */ + NZERROR_TK_KEYTYPE = 29243, /* Unknown key type. */ + + NZERROR_TK_PLSQL_NO_WRL = 29244, + /* Wallet resource locator not specified to PL/SQL function */ + + NZERROR_TK_CE_FUNC = 29245, /* Unknown crypto engine function */ + NZERROR_TK_TDU_FORMAT = 29246, /* Unknown TDU format */ + NZERROR_TK_NOTOPEN = 29247, /* Object must be open */ + NZERROR_TK_WRLTYPE = 29248, /* Bad WRL type */ + NZERROR_TK_CE_STATE = 29249, /* Bad state specified for the crypto engine */ + + /* After 29249, use error numbers in block 43000 - 43499 */ + NZERROR_PKCS11_LIBRARY_NOT_FOUND = 43000, /* PKCS #11 library not found */ + NZERROR_PKCS11_TOKEN_NOT_FOUND = 43001, + /* can't find token with given label*/ + NZERROR_PKCS11_BAD_PASSPHRASE = 43002, /* passphrase is incorrect/expired */ + NZERROR_PKCS11_GET_FUNC_LIST = 43003, /* C_GetFunctionList returned error */ + NZERROR_PKCS11_INITIALIZE = 43004, /* C_Initialize returned error */ + NZERROR_PKCS11_NO_TOKENS_PRESENT = 43005, /* No tokens present */ + NZERROR_PKCS11_GET_SLOT_LIST = 43006, /* C_GetSlotList returned error */ + + NZERROR_PKCS11_GET_TOKEN_INFO = 43008, /* C_GetTokenInfo returned error */ + NZERROR_PKCS11_SYMBOL_NOT_FOUND = 43009, /* Symbol not found in PKCS11 lib */ + + NZERROR_PKCS11_TOKEN_LOGIN_FAILED = 43011, /* Token login failed */ + + NZERROR_PKCS11_CHANGE_PROVIDERS_ERROR = 43013, /* Change providers error */ + NZERROR_PKCS11_GET_PRIVATE_KEY_ERROR = 43014, + /* Error trying to find private key on token */ + NZERROR_PKCS11_CREATE_KEYPAIR_ERROR = 43015, /* Key pair gen error */ + NZERROR_PKCS11_WALLET_CONTAINS_P11_INFO = 43016, /* Wallet already contains + pkcs11 info */ + NZERROR_PKCS11_NO_CERT_ON_TOKEN = 43017, /* No cert found on token */ + NZERROR_PKCS11_NO_USER_CERT_ON_TOKEN = 43018, /*No user cert found on token*/ + NZERROR_PKCS11_NO_CERT_ON_TOKEN_WITH_GIVEN_LABEL = 43019, /*No cert found on token with given certificate label.*/ + NZERROR_PKCS11_MULTIPLE_CERTS_ON_TOKEN_WITH_GIVEN_LABEL = 43020, /*Multiple certs found on token with given certificate label.*/ + NZERROR_PKCS11_CERT_WITH_LABEL_NOT_USER_CERT = 43021, /*Cert with given cert is not a user cert because no corresponding pvt key found on token */ + + /* RSA ERRORS 43050 - 43059 */ + NZERROR_BIND_SERVICE_ERROR = 43050, /* C_BindService returned error */ + NZERROR_CREATE_KEY_OBJ_ERROR = 43051, /* B_CreateKeyObject returned error */ + NZERROR_GET_CERT_FIELDS = 43052, /* C_GetCertFields returned error */ + NZERROR_CREATE_PKCS10_OBJECT = 43053, + /* C_CreatePKCS10Object returned error */ + NZERROR_SET_PKCS10_FIELDS = 43054, /* C_SetPKCS10Fields returned error */ + NZERROR_SIGN_CERT_REQUEST = 43055, /* C_SignCertRequest returned error */ + NZERROR_GET_PKCS10_DER = 43056, /* C_GetPKCS10DER returned error */ + NZERROR_INITIALIZE_CERTC = 43057, /* C_InitializeCertC returned error */ + NZERROR_INSERT_PRIVATE_KEY = 43058, /* C_InsertPrivateKey returned error */ + NZERROR_RSA_ERROR = 43059, /* RSA error. See trace output */ + + /* slts ERRORS 43060 - 43069 */ + NZERROR_SLTSCTX_INIT_FAILED = 43060, /* sltsini() returned error */ + NZERROR_SLTSKYC_FAILED = 43061, /* sltskyc() returned error */ + NZERROR_SLTSCTX_TERM_FAILED = 43062, /* sltster() returned error */ + NZERROR_SLTSKYS_FAILED = 43063, /* sltskys() returned error */ + + NZERROR_INVALID_HEADER_LENGTH = 43070, /* bad sso header length */ + NZERROR_WALLET_CONTAINS_USER_CREDENTIALS = 43071, /* wallet not empty */ + NZERROR_CANNOT_MODIFY_AL = 43072, /* Cannot modify AL wallet */ + NZERROR_FILE_LOCK_FAILED = 43073, /* Cannot lock wallet file */ + + NZERROR_CSF_ALIAS_INVALID = 43100, /* alias is invalid */ + NZERROR_CSF_KEY_INVALID = 43101, /* key invalid */ + NZERROR_CSF_CRED_NOT_SUPPORTED = 43102, /* only pwd cred supported */ + NZERROR_CSF_HOSTNAME = 43103, /* hostname error */ + NZERROR_CSF_XML = 43104, /* XmlCreate error. See trace */ + NZERROR_CSF_WALLET_NOT_SPECIFIED = 43105, /* no wallet specified */ + NZERROR_CSF_MAP_NOT_IN_STORE = 43106, /* map does not exist in store */ + NZERROR_CSF_KEY_NOT_IN_STORE = 43107, /* key does not exist in store */ + NZERROR_CSF_ENTRY_EXISTS = 43108, /* entry with map/key exists */ + + NZERROR_LX_ERROR = 43120, /* lx api returned error */ + + NZERROR_LAST_ERROR = 43499, /* Last available error */ + /* MAXIMUM ERROR NUMBER IS 43499 */ + + /* + * DO NOT JUST INSERT NEW ERRORS IN ANY OLD PLACE. New errors should be + * added such the current error retains their integer values. Duplicate + * values will cause compiler errors. + */ + NZERROR_THIS_MUST_BE_LAST + +} nzerror; + +/* + * Macro to convert SSL errors to Oracle errors. As SSL errors are negative + * and Oracle numbers are positive, the following needs to be done. + * 1. The base error number, which is the highest, is added to the + * SSL error to get the index into the number range. + * 2. The result is added to the base Oracle number to get the Oracle error. + */ +#define NZERROR_SSL_TO_ORACLE(ssl_error_) \ + ((ssl_error_ == SSLNoErr) \ + ? NZERROR_OK \ + : (nzerror) ((ssl_error_ - SSLMemoryErr) + (uword) NZERROR_SSLMemoryErr)) +#endif /* NZERROR_ORACLE */ diff --git a/OCI/include/nzt.h b/OCI/include/nzt.h new file mode 100644 index 0000000..42fec33 --- /dev/null +++ b/OCI/include/nzt.h @@ -0,0 +1,2387 @@ +/* DISABLE check_long_lines */ + +/* Copyright (c) 1996, 2007, Oracle. All rights reserved. */ +/* Copyright (c) 1996, 2007, Oracle. All rights reserved. */ + +/* + * + */ + +/* + * NAME + * nzt.h + * + * DESCRIPTION + * Toolkit public declarations. + * + * PUBLIC FUNCTIONS + * nztwOpenWallet - Open a wallet based on a WRL and pwd. + * nztwCloseWallet - Close a wallet. + * + nztwCreateWallet - Create a new wallet. + * + nztwDestroyWallet - Destroy an existing wallet. + * nztwRetrievePersonaCopy - Retieve a copy of a particular persona. + * + nzteStorePersona - Store a persona in the wallet. + * nzteOpenPersona - Open a persona. + * nzteClosePersona - Close a persona. + * + nzteRemovePersona - Remove a persona from a wallet. + * + nzteCreatePersona - Create a persona. + * nzteDestroyPersona - Destroy a persona. + * nztiStoreTrustedIdentity - Store an identity with associated trust. + * nzteRetrieveTrustedIdentCopy - Retrieves a trusted identity from persona + * + nzteSetProtection - Modify the protection set in a persona. + * + nzteGetProtection - Get the protection set in a persona + * nztePriKey - Get the Private Key (X509 Only) + * nzteMyCert - Get the Certificate (X509 only) + * nzteX509CreatePersona - Create a persona given an X509 Certificate. + * + nztiRemoveIdentity - Remove an identity from a persona. + * nztiCreateIdentity - Create an identity. + * nztiDuplicateIdentity - Create a complete copy of an identity. + * nztiAbortIdentity - Discard an unstored identity. + * nztidGetIdentityDesc - Gets Identity Description from Identity. + * nztidFreeIdentityDesc - Frees memory for Identity Desc object. + * nztSign - Generate an attached signature. + * + nztxSignExpansion - Determine size of signature. + * nztVerify - Verify an attached signature. + * nztValidate - Validate an identity. + * nztsd_SignDetached - Generate a detached signature. + * + nztxsd_SignDetachedExpansion - Determine size of detached signature. + * nztved_VerifyDetached - Verify a detached signature. + * + nztEncrypt - Symmetric key encryption. + * + nztxEncryptExpansion - Determine the tdu length for encryption. + * + nztDecrypt - Symmetric key decryption. + * + nztEnvelope - Sign then encrypt data for recipient(s). + * + nztDeEnvelope - Reverse nztEnvelope. + * + nztKeyedHash - Generate keyed hash. + * + nztxKeyedHashExpansion - Determine size of TDU for keyed hash. + * nztHash - Generate hash. + * + nztxHashExpansion - Determine the size of the TDU for a hash. + * nztSeedRandom - See the random number generator. + * nztrb_RandomBytes - Generate a series of random bytes. + * nztrn_RandomNumber - Generate a random number. + * nztbbInitBlock - Initialize a buffer block. + * nztbbReuseBlock - Reuse a buffer block. + * nztbbSizeBlock - Find the size of the buffer block. + * nztbbGrowBlock - Grow initialized buffer block by 'inc' bytes. + * nztbbPurgeBlock - Purge the memory used within a buffer block. + * nztbbSetBlock - Set block to known state. + * nztkec_PKEncrypt - Encrypt data then encrypt key for recipient. + * nztkdc_PKDecrypt - Decrypt PKEncrypt'ed data. + * nztific_FreeIdentityContent - Free the contents of an identity. + * nztifdn - Create an identity from a distinguished name + * nztcts_CipherSpecToStr - Converts the Cipher Spec Code To String + * nztiae_IsAuthEnabled - Checks to see if Authentication is Enabled + * in the current Cipher Spec. + * nztiae_IsEncrEnabled - Checks to see if Encryption is Enabled + * in the current Cipher Spec. + * nztiae_IsHashEnabled - Checks to see if Hashing is Enabled + * in the current Cipher Spec. + * nztwGetCertInfo - Get peer certificate info + * + * NOTE: the '+' indicates that these functions are UNSUPPORTED at this time. + * + * NOTES + * + * MODIFIED + * shiahuan 11/28/07 - + * skalyana 08/15/07 - + * pkale 09/28/06 - Bug 5565668: Removed __STDC__ + * tnallath 09/22/05 - + * rchahal 07/27/04 - add keyusage + * srtata 11/10/03 - fix nztSetAppDefaultLocation header + * rchahal 10/15/03 - bug 2513821 + * rchahal 11/11/02 - pkcs11 support + * akoyfman 07/05/02 - adding secret store to persona + * supriya 10/11/01 - Fix for bug # 2015732 + * ajacobs 04/04/01 - make NZT_REGISTRY_WRL always available + * ajacobs 03/06/01 - olint fix + * ajacobs 03/02/01 - Add GetCertInfo + * supriya 02/23/01 - Move nzttKPUsage from nzt0.h + * rchahal 01/26/01 - olint fixes + * supriya 12/07/00 - Change fn name + * supriya 12/01/00 - Certificate API's needed for iAS + * supriya 06/19/00 - Adding definitions for MCS and ENTR + * lkethana 05/31/00 - multiple cert support + * skanjila 06/25/99 - Remove nztcts_CipherSpecToStr() to NZOS. + * skanjila 06/23/99 - Change API of nztcts_CipherSpecToStr. + * lkethana 06/18/99 - rem nztIPrivateAlloc, etc + * lkethana 06/10/99 - changing size_t to ub4 + * lkethana 06/02/99 - add api for getting auth/encry/hash capability of c + * arswamin 12/28/98 - add NZT_MAX_MD5. + * arswamin 12/21/98 - change signature of compareDN + * qdinh 12/21/98 - change size_t to ub4. + * inetwork 11/22/98 - Removing NZDEPRECATED definition + * amthakur 09/14/98 - deprecating and updating the c-structures. + * arswamin 09/24/98 - adding NZTTWRL_NULL for SSO support. + * amthakur 07/30/98 - changing the prototype of nztGetCertChain. + * qdinh 05/01/98 - add NZTTIDENTTYPE_INVALID_TYPE + * qdinh 04/17/98 - add NZTTWRL_ORACLE. + * ascott 10/08/97 - implement nztiStoreTrustedIdentity + * ascott 10/07/97 - add nztiGetIdentityDesc + * ascott 09/28/97 - clarify prototype comments and error codes + * ascott 09/05/97 - update identity: create, destroy, duplicate + * ascott 08/21/97 - add GetCert and GetPriKey + * ascott 08/07/97 - add other WRL settings + * asriniva 03/25/97 - Add ANSI prototypes + * rwessman 03/19/97 - Added prototypes for nztific_FreeIdentityContent() + * asriniva 03/11/97 - Fix olint errors + * sdange 02/28/97 - Removed inclusion of nz0decl.h + * sdange 02/18/97 - Moved nzt specific declarations from nz0decl.h + * asriniva 01/21/97 - Remove prototypes. + * asriniva 10/31/96 - Include oratypes.h + * asriniva 10/15/96 - Declare buffer block helper functions + * asriniva 10/08/96 - First pass at wallet open/close + * asriniva 10/04/96 - Add random number seed function + * asriniva 10/03/96 - Reorder parameters in nztbbSetBlock + * asriniva 10/03/96 - Keep editing. + * asriniva 10/03/96 - Continued edits. + * asriniva 10/02/96 - Continue editing. + * asriniva 09/26/96 - + */ + +/* ENABLE check_long_lines */ + +#ifndef NZT_ORACLE +#define NZT_ORACLE + +#ifndef ORATYPES +# include +#endif /* ORATYPES */ + +#ifndef NZERROR_ORACLE +# include /* NZ error type */ +#endif /* NZERROR_ORACLE */ + + +#define NZT_MAX_SHA1 20 +#define NZT_MAX_MD5 16 + +/***************************************/ +/* PUBLIC CONSTANTS, MACROS, AND TYPES */ +/***************************************/ + +/* + * Wallet Resource Locator Type Strings + * + * WRL TYPE PARAMETERS BEHAVIOR + * ======== ========== ===================================== + * default: Uses directory defined by the parameter + * SNZD_DEFAULT_FILE_DIRECTORY which in + * unix is "$HOME/oracle/oss" + * + * file: file path Find the Oracle wallet in this directory. + * example: file: + * + * sqlnet: In this case, the directory path will be + * retrieved from the sqlnet.ora file under + * the oss.source.my_wallet parameter. + * + * mcs: Microsoft WRL. + * + * entr: dir path Entrust WRL. eg: ENTR: + * + */ +/* Note that there is no NZT_NULL_WRL. Instead look in snzd.h for DEFAULT_WRP + * which is used in our new defaulting mechanism. The NZT_DEFAULT_WRL + * should be deprecated. + */ +#define NZT_DEFAULT_WRL ((text *)"default:") +#define NZT_SQLNET_WRL ((text *)"sqlnet:") +#define NZT_FILE_WRL ((text *)"file:") +#define NZT_ENTR_WRL ((text *)"entr:") +#define NZT_MCS_WRL ((text *)"mcs:") +#define NZT_ORACLE_WRL ((text *)"oracle:") +#define NZT_REGISTRY_WRL ((text *)"reg:") + +enum nzttwrl +{ + NZTTWRL_DEFAULT = 1, /* Default, use SNZD_DEFAULT_FILE_DIRECTORY */ + NZTTWRL_SQLNET, /* Use oss.source.my_wallet in sqlnet.ora file */ + NZTTWRL_FILE, /* Find the oracle wallet in this directory */ + NZTTWRL_ENTR, /* Find the entrust profile in this directory */ + NZTTWRL_MCS, /* WRL for Microsoft */ + NZTTWRL_ORACLE, /* Get the wallet from OSS db */ + NZTTWRL_NULL, /* New SSO defaulting mechanism */ + NZTTWRL_REGISTRY /* Find the wallet in Windows Registry */ +}; +typedef enum nzttwrl nzttwrl; + +#ifndef NZ0DECL_ORACLE + /* + * With the elimination of nz0decl.h from public, we need this + * redundant typedef. + */ + typedef struct nzctx nzctx; + typedef struct nzstrc nzstrc; + typedef struct nzosContext nzosContext; +#endif /* NZ0DECL_ORACLE */ + +/* Moved from nz0decl.h */ + +typedef struct nzttIdentity nzttIdentity; +typedef struct nzttIdentityPrivate nzttIdentityPrivate; +typedef struct nzttPersona nzttPersona; +typedef struct nzttPersonaPrivate nzttPersonaPrivate; +typedef struct nzttWallet nzttWallet; +typedef struct nzttWalletPrivate nzttWalletPrivate; +typedef struct nzttWalletObj nzttWalletObj; /* For wallet object */ +typedef struct nzssEntry nzssEntry; /* For secretstore */ +typedef struct nzpkcs11_Info nzpkcs11_Info; + +/* + * Crypto Engine State + * + * Once the crypto engine (CE) has been initialized for a particular + * cipher, it is either at the initial state, or it is continuing to + * use the cipher. NZTCES_END is used to change the state back to + * initialized and flush any remaining output. NZTTCES_RESET can be + * used to change the state back to initialized and throw away any + * remaining output. + */ +enum nzttces +{ + NZTTCES_CONTINUE = 1, /* Continue processing input */ + NZTTCES_END, /* End processing input */ + NZTTCES_RESET /* Reset processing and skip generating output */ +}; +typedef enum nzttces nzttces; + +/* + * Crypto Engine Functions + * + * List of crypto engine categories; used to index into protection + * vector. + */ +enum nzttcef +{ + NZTTCEF_DETACHEDSIGNATURE = 1, /* Signature, detached from content */ + NZTTCEF_SIGNATURE, /* Signature combined with content */ + NZTTCEF_ENVELOPING, /* Signature and encryption with content */ + NZTTCEF_PKENCRYPTION, /* Encryption for one or more recipients */ + NZTTCEF_ENCRYPTION, /* Symmetric encryption */ + NZTTCEF_KEYEDHASH, /* Keyed hash/checkusm */ + NZTTCEF_HASH, /* Hash/checsum */ + NZTTCEF_RANDOM, /* Random byte generation */ + + NZTTCEF_LAST /* Used for array size */ +}; +typedef enum nzttcef nzttcef; + +/* + * State of the persona. + */ +enum nzttState +{ + NZTTSTATE_EMPTY = 0, /* is not in any state(senseless???) */ + NZTTSTATE_REQUESTED, /* cert-request */ + NZTTSTATE_READY, /* certificate */ + NZTTSTATE_INVALID, /* certificate */ + NZTTSTATE_RENEWAL /* renewal-requested */ +}; +typedef enum nzttState nzttState; + +/* + * Cert-version types + * + * This is used to quickly look-up the cert-type + */ +enum nzttVersion +{ + NZTTVERSION_X509v1 = 1, /* X.509v1 */ + NZTTVERSION_X509v3, /* X.509v3 */ +#ifdef NZDEPRECATED + NZTTVERSION_SYMMETRIC, /* Symmetric */ +#endif + NZTTVERSION_INVALID_TYPE /* For Initialization */ +}; +typedef enum nzttVersion nzttVersion; + +/* + * Cipher Types + * + * List of all cryptographic algorithms, some of which may not be + * available. + */ +enum nzttCipherType +{ + NZTTCIPHERTYPE_RSA = 1, /* RSA public key */ + NZTTCIPHERTYPE_DES, /* DES */ + NZTTCIPHERTYPE_RC4, /* RC4 */ + NZTTCIPHERTYPE_MD5DES, /* DES encrypted MD5 with salt (PBE) */ + NZTTCIPHERTYPE_MD5RC2, /* RC2 encrypted MD5 with salt (PBE) */ + NZTTCIPHERTYPE_MD5, /* MD5 */ + NZTTCIPHERTYPE_SHA /* SHA */ +}; +typedef enum nzttCipherType nzttCipherType; + +/* + * TDU Formats + * + * List of possible toolkit data unit (TDU) formats. Depending on the + * function and cipher used some may be not be available. + */ +enum nztttdufmt +{ + NZTTTDUFMT_PKCS7 = 1, /* PKCS7 format */ + NZTTTDUFMT_RSAPAD, /* RSA padded format */ + NZTTTDUFMT_ORACLEv1, /* Oracle v1 format */ + NZTTTDUFMT_LAST /* Used for array size */ +}; +typedef enum nztttdufmt nztttdufmt; + +/* + * Validate State + * + * Possible validation states an identity can be in. + */ +enum nzttValState +{ + NZTTVALSTATE_NONE = 1, /* Needs to be validated */ + NZTTVALSTATE_GOOD, /* Validated */ + NZTTVALSTATE_REVOKED /* Failed to validate */ +}; +typedef enum nzttValState nzttValState; + +/* + * Policy Fields <----NEW (09/14/98) + * + * Policies enforced + */ +enum nzttPolicy +{ + NZTTPOLICY_NONE = 0, + NZTTPOLICY_RETRY_1, /* number of retries for decryption = 1 */ + NZTTPOLICY_RETRY_2, /* number of retries for decryption = 2 */ + NZTTPOLICY_RETRY_3 /* number of retries for decryption = 3 */ +}; +typedef enum nzttPolicy nzttPolicy; + +/* + * Persona Usage <----NEW (09/14/98) + * + * what a persona will be used for? + */ + +#ifdef NZDEPRECATED_MULTIPLECERTS +enum nzttUsage +{ + NZTTUSAGE_NONE = 0, + NZTTUSAGE_SSL /* persona for SSL usage */ +}; +typedef enum nzttUsage nzttUsage; +#endif + +/* + * Personas and identities have unique id's that are represented with + * 128 bits. + */ +typedef ub1 nzttID[16]; + +/* + * Identity Types + * + * List of all Identity types.. + */ +enum nzttIdentType +{ + NZTTIDENTITYTYPE_INVALID_TYPE = 0, + NZTTIDENTITYTYPE_CERTIFICTAE, + NZTTIDENTITYTYPE_CERT_REQ, + NZTTIDENTITYTYPE_RENEW_CERT_REQ, + NZTTIDENTITYTYPE_CLEAR_ETP, + NZTTIDENTITYTYPE_CLEAR_UTP, + NZTTIDENTITYTYPE_CLEAR_PTP +}; +typedef enum nzttIdentType nzttIdentType; + +typedef ub4 nzttKPUsage; +/* IF new types are added nztiMUS should be changed */ +#define NZTTKPUSAGE_NONE 0 +#define NZTTKPUSAGE_SSL 1 /* SSL Server */ +#define NZTTKPUSAGE_SMIME_ENCR 2 +#define NZTTKPUSAGE_SMIME_SIGN 4 +#define NZTTKPUSAGE_CODE_SIGN 8 +#define NZTTKPUSAGE_CERT_SIGN 16 +#define NZTTKPUSAGE_SSL_CLIENT 32 /* SSL Client */ +#define NZTTKPUSAGE_INVALID_USE 0xffff + + +/* + * Timestamp as 32 bit quantity in UTC. + */ +typedef ub1 nzttTStamp[4]; + +/* + * Buffer Block + * + * A function that needs to fill (and possibly grow) an output buffer + * uses an output parameter block to describe each buffer. + * + * The flags_nzttBufferBlock member tells the function whether the + * buffer can be grown or not. If flags_nzttBufferBlock is 0, then + * the buffer will be realloc'ed automatically. + * + * The buflen_nzttBufferBLock member is set to the length of the + * buffer before the function is called and will be the length of the + * buffer when the function is finished. If buflen_nzttBufferBlock is + * 0, then the initial pointer stored in pobj_nzttBufferBlock is + * ignored. + * + * The objlen_nzttBufferBlock member is set to the length of the + * object stored in the buffer when the function is finished. If the + * initial buffer had a non-0 length, then it is possible that the + * object length is shorter than the buffer length. + * + * The pobj_nzttBufferBlock member is a pointer to the output object. + */ +struct nzttBufferBlock +{ +# define NZT_NO_AUTO_REALLOC 0x1 + + uword flags_nzttBufferBlock; /* Flags */ + ub4 buflen_nzttBufferBlock; /* Total length of buffer */ + ub4 usedlen_nzttBufferBlock; /* Length of used buffer part */ + ub1 *buffer_nzttBufferBlock; /* Pointer to buffer */ +}; +typedef struct nzttBufferBlock nzttBufferBlock; + +/* + * Wallet. + */ +struct nzttWallet +{ + ub1 *ldapName_nzttWallet; /* user's LDAP Name */ + ub4 ldapNamelen_nzttWallet; /* len of user's LDAP Name */ + nzttPolicy securePolicy_nzttWallet; /* secured-policy of the wallet */ + nzttPolicy openPolicy_nzttWallet; /* open-policy of the wallet */ + nzttPersona *persona_nzttWallet; /* List of personas in wallet */ + nzttWalletPrivate *private_nzttWallet; /* Private wallet information */ +#ifdef NZDEPRECATED + ub4 npersona_nzttWallet; /* Number of personas */ +#endif +}; + +/* + * The wallet contains, one or more personas. A persona always + * contains its private key and its identity. It may also contain + * other 3rd party identites. All identities qualified with trust + * where the qualifier can indicate anything from untrusted to trusted + * for specific operations. + */ + +/* + * Persona + * + * Structure containing information about a persona. + */ +struct nzttPersona +{ + ub1 *genericName_nzttPersona; /* user-friendly persona name */ + ub4 genericNamelen_nzttPersona; /* persona-name length */ + nzttPersonaPrivate *private_nzttPersona; /* Opaque part of persona */ + nzttIdentity *mycertreqs_nzttPersona; /* My cert-requests */ + nzttIdentity *mycerts_nzttPersona; /* My certificates */ + nzttIdentity *mytps_nzttPersona; /* List of trusted identities */ + nzssEntry *mystore_nzttPersona; /* List of secrets */ + nzpkcs11_Info *mypkcs11Info_nzttPersona; /* PKCS11 token info */ + struct nzttPersona *next_nzttPersona; /* Next persona */ +#ifdef NZDEPRECATED_MULTIPLECERTS + /* As Persona has multiple certs for different + usages, Persona Usage does not mean anything. Similarly + each key pair has its own state and Persona state itself + does not mean anything. - lk 5/31/00 + */ + nzttUsage usage_nzttPersona; /* persona usage; SSL/SET/.. */ + nzttState state_nzttPersona; /* persona state-requested/ready */ + ub4 ntps_nzttPersona; /* Num of trusted identities */ +#endif +}; + +/* + * Identity + * + * Structure containing information about an identity. + * + * NOTE + * -- the next_trustpoint field only applies to trusted identities and + * has no meaning (i.e. is NULL) for self identities. + */ +struct nzttIdentity +{ + text *dn_nzttIdentity; /* Alias */ + ub4 dnlen_nzttIdentity; /* Length of alias */ + text *comment_nzttIdentity; /* Comment */ + ub4 commentlen_nzttIdentity; /* Length of comment */ + nzttIdentityPrivate *private_nzttIdentity; /* Opaque part of identity */ + nzttIdentity *next_nzttIdentity; /* next identity in list */ +}; + +struct nzttB64Cert +{ + ub1 *b64Cert_nzttB64Cert; + ub4 b64Certlen_nzttB64Cert; + struct nzttB64Cert *next_nzttB64Cert; +}; +typedef struct nzttB64Cert nzttB64Cert; + + +struct nzttPKCS7ProtInfo +{ + nzttCipherType mictype_nzttPKCS7ProtInfo; /* Hash cipher */ + nzttCipherType symmtype_nzttPKCS7ProtInfo; /* Symmetric cipher */ + ub4 keylen_nzttPKCS7ProtInfo; /* Length of key to use */ +}; +typedef struct nzttPKCS7ProtInfo nzttPKCS7ProtInfo; + +/* + * Protection Information. + * + * Information specific to a type of protection. + */ +union nzttProtInfo +{ + nzttPKCS7ProtInfo pkcs7_nzttProtInfo; +}; +typedef union nzttProtInfo nzttProtInfo; + +/* + * A description of a persona so that the toolkit can create one. A + * persona can be symmetric or asymmetric and both contain an + * identity. The identity for an asymmetric persona will be the + * certificate and the identity for the symmetric persona will be + * descriptive information about the persona. In either case, an + * identity will have been created before the persona is created. + * + * A persona can be stored separately from the wallet that references + * it. By default, a persona is stored with the wallet (it inherits + * with WRL used to open the wallet). If a WRL is specified, then it + * is used to store the actuall persona and the wallet will have a + * reference to it. + */ +struct nzttPersonaDesc +{ + ub4 privlen_nzttPersonaDesc; /* Length of private info (key)*/ + ub1 *priv_nzttPersonaDesc; /* Private information */ + ub4 prllen_nzttPersonaDesc; /* Length of PRL */ + text *prl_nzttPersonaDesc; /* PRL for storage */ + ub4 aliaslen_nzttPersonaDesc; /* Length of alias */ + text *alias_nzttPersonaDesc; /* Alias */ + ub4 longlen_nzttPersonaDesc; /* Length of longer description*/ + text *long_nzttPersonaDesc; /* Longer persona description */ +}; +typedef struct nzttPersonaDesc nzttPersonaDesc; + +/* + * A description of an identity so that the toolkit can create one. + * Since an identity can be symmetric or asymmetric, the asymmetric + * identity information will not be used when a symmetric identity is + * created. This means the publen_nzttIdentityDesc and + * pub_nzttIdentityDesc members will not be used when creating a + * symmetric identity. + */ +struct nzttIdentityDesc +{ + ub4 publen_nzttIdentityDesc; /* Length of identity */ + ub1 *pub_nzttIdentityDesc; /* Type specific identity */ + ub4 dnlen_nzttIdentityDesc; /* Length of alias */ + text *dn_nzttIdentityDesc; /* Alias */ + ub4 longlen_nzttIdentityDesc; /* Length of longer description */ + text *long_nzttIdentityDesc; /* Longer description */ + ub4 quallen_nzttIdentityDesc; /* Length of trust qualifier */ + text *trustqual_nzttIdentityDesc; /* Trust qualifier */ +}; +typedef struct nzttIdentityDesc nzttIdentityDesc; + +/********************************/ +/* PUBLIC FUNCTION DECLARATIONS */ +/********************************/ + +/*---------------------- nztwOpenWallet ----------------------*/ + +/* + * NAME + * nztwOpenWallet - Open a wallet based on a wallet Resource Locator (WRL). + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wrllen {IN} Length of WRL. + * wrl {IN} WRL. + * pwdlen {IN} Length of password. + * pwd {IN} Password. + * wallet {IN/OUT} Initialized wallet structure. + * + * NOTES + * The syntax for a WRL is :. + * + * Wallet Type Wallet Type Parameters. + * ----------- ---------------------- + * File Pathname (e.g. "file:/home/asriniva") + * Oracle Connect string (e.g. "oracle:scott/tiger@oss") + * + * There are also defaults. If the WRL is NZT_DEFAULT_WRL, then + * the platform specific WRL default is used. If only the wallet + * type is specified, then the WRL type specific default is used + * (e.g. "oracle:") + * + * There is an implication with Oracle that should be stated: An + * Oracle based wallet can be implemented in a user's private space + * or in world readable space. + * + * When the wallet is opened, the password is verified by hashing + * it and comparing against the password hash stored with the + * wallet. The list of personas (and their associated identities) + * is built and stored into the wallet structure. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_RIO_OPEN RIO could not open wallet (see network trace file). + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_TK_WRLTYPE WRL type is not known. + * NZERROR_TK_WRLPARM WRL parm does not match type. + */ +nzerror nztwOpenWallet( nzctx *, ub4, text *, ub4, text *, + nzttWallet * ); + + +/*---------------------- nztwCloseWallet ----------------------*/ + +/* + * NAME + * nztwCloseWallet - Close a wallet + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wallet {IN/OUT} Wallet. + * + * NOTES + * Closing a wallet also closes all personas associated with that + * wallet. It does not cause a persona to automatically be saved + * if it has changed. The implication is that a persona can be + * modified by an application but if it is not explicitly saved it + * reverts back to what was in the wallet. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_RIO_CLOSE RIO could not close wallet (see network trace file). + */ +nzerror nztwCloseWallet( nzctx *, nzttWallet * ); + +/*--------------------nztwGetCertInfo----------------------------*/ +/****NOTE: This function is a temporary hack.****/ +/****DO NOT CALL. It will soon disappear.****/ +nzerror nztwGetCertInfo( nzctx *nz_context, + nzosContext *nzosCtx, + nzttWallet *walletRef, + void *peerCert ); + + +/*------------------------ nztwConstructWallet -----------------------*/ +/* + * + * nzerror nztwConstructWallet( nzctx *oss_context, + * nzttPolicy openPolicy, + * nzttPolicy securePolicy, + * ub1 *ldapName, + * ub4 ldapNamelen, + * nzstrc *wrl, + * nzttPersona *personas, + * nzttWallet **wallet ); + */ + +/*---------------------- nztwRetrievePersonaCopy ----------------------*/ + +/* + * NAME + * nztwRetrievePersonaCopy - Retrieves a persona based from wallet + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wallet {IN} Wallet. + * index {IN} Which wallet index to remove (first persona is zero). + * persona {OUT} Persona found. + * + * NOTES + * Retrieves a persona from the wallet based on the index number passed + * in. This persona is a COPY of the one stored in the wallet, therefore + * it is perfectly fine for the wallet to be closed after this call is + * made. + * + * The caller is responsible for disposing of the persona when completed. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztwRetrievePersonaCopy( nzctx *, nzttWallet *, ub4, + nzttPersona ** ); + + +/*---------------------- nztwRetrievePersonaCopyByName ----------------------*/ + +/* + * NAME + * nztwRetrievePersonaCopyByName - Retrieves a persona based on its name. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wallet {IN} Wallet. + * name {IN} Name of the persona + * persona {OUT} Persona found. + * + * NOTES + * Retrieves a persona from the wallet based on the name of the persona. + * This persona is a COPY of the one stored in the wallet, therefore + * it is perfectly fine for the wallet to be closed after this call is + * made. + * + * The caller is responsible for disposing of the persona when completed. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztwRetrievePersonaCopyByName( nzctx *, nzttWallet *, char *, + nzttPersona ** ); + +/*---------------------- nzteOpenPersona ----------------------*/ + +/* + * NAME + * nzteOpenPersona - Open a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password failed to decrypt persona. + * NZERROR_TK_BADPRL Persona resource locator did not work. + * NZERROR_RIO_OPEN Could not open persona (see network trace file). + */ +nzerror nzteOpenPersona( nzctx *, nzttPersona * ); + +/*--------------------- nzteClosePersona ---------------------*/ + +/* + * NAME + * nzteClosePersona - Close a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * Closing a persona does not store the persona, it simply releases + * the memory associated with the crypto engine. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nzteClosePersona( nzctx *, nzttPersona * ); + +/*--------------------- nzteDestroyPersona ---------------------*/ + +/* + * NAME + * nzteDestroyPersona - Destroy a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * The persona is destroyd in the open state, but it will + * not be associated with a wallet. + * + * The persona parameter is doubly indirect so that at the + * conclusion of the function, the pointer can be set to NULL. + * + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_TYPE Unsupported itype/ctype combination. + * NZERROR_TK_PARMS Error in persona description. + */ +nzerror nzteDestroyPersona( nzctx *, nzttPersona ** ); + +/*---------------------- nzteRetrieveTrustedIdentCopy ----------------------*/ + +/* + * NAME + * nzteRetrieveTrustedIdentCopy - Retrieves a trusted identity from persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * index {IN} Which wallet index to remove (first element is zero). + * identity {OUT} Trusted Identity from this persona. + * + * NOTES + * Retrieves a trusted identity from the persona based on the index + * number passed in. This identity is a COPY of the one stored in + * the persona, therefore it is perfectly fine to close the persona + * after this call is made. + * + * The caller is responsible for freeing the memory of this object + * by calling nztiAbortIdentity it is no longer needed + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nzteRetrieveTrustedIdentCopy( nzctx *, nzttPersona *, ub4, + nzttIdentity ** ); + +/*--------------------- nztePriKey ---------------------*/ + +/* + * NAME + * nztePriKey - Get the decrypted Private Key for the Persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * vkey {OUT} Private Key [B_KEY_OBJ] + * vkey_len {OUT} Private Key Length + * + * NOTES + * This funiction will only work for X.509 based persona which contain + * a private key. + * A copy of the private key is returned to the caller so that they do not + * have to worry about the key changeing "underneath them". + * Memory will be allocated for the vkey and therefore, the CALLER + * will be responsible for freeing this memory. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_NO_MEMORY ossctx is null. + * NZERROR_TK_BADPRL Persona resource locator did not work. + */ +nzerror nztePriKey( nzctx *, nzttPersona *, ub1 **, ub4 * ); + +/*--------------------- nzteMyCert ---------------------*/ + +/* + * NAME + * nzteMyCert - Get the X.509 Certificate for a persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * cert {OUT} X.509 Certificate [BER encoded] + * cert_len {OUT} Certificate length + * + * NOTES + * This funiction will only work for X.509 based persona which contain + * a certificate for the self identity. + * A copy of the certificate is returned to the caller so that they do not + * have to worry about the certificate changeing "underneath them". + * Memory will be allocated for the cert and therefore, the CALLER + * will be responsible for freeing this memory. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_NO_MEMORY ossctx is null. + */ +nzerror nzteMyCert( nzctx *, nzttPersona *, ub1 **, ub4 * ); + +/*--------------------- nzteX509CreatePersona ---------------------*/ + +/* + * NAME + * nzteX509CreatePersona - Given a BER X.509 cert, create a persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * cert {IN} X.509 Certificate [BER encoded] + * cert_len {IN} Certificate length + * persona {OUT} Persona. + * + * NOTES + * Memory will be allocated for the persona and therefore, the CALLER + * will be responsible for freeing this memory. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_NO_MEMORY ossctx is null. + */ +nzerror nzteX509CreatePersona( nzctx *, ub1 *, ub4, nzttPersona ** ); + +/*-------------------- nztiCreateIdentity --------------------*/ + +/* + * NAME + * nztiCreateIdentity - Create an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * itype {IN} Identity type. + * desc {IN} Description of identity. + * identity {IN/OUT} Identity. + * + * NOTES + * Memory is only allocated for the identity structure. The elements in + * the description struct are not copied. Rather their pointers are copied + * into the identity structure. Therefore, the caller should not free + * the elements referenced by the desc. These elements will be freed + * when the nztiDestroyIdentity is called. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_PARMS Error in description. + */ +nzerror nztiCreateIdentity( nzctx *, nzttVersion, nzttIdentityDesc *, + nzttIdentity ** ); + +#ifdef NZ_OLD_TOOLS +/*-------------------- nztiDuplicateIdentity --------------------*/ + +/* + * NAME + * nztiDuplicateIdentity - Duplicate an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN} Target Identity. + * new_identity {IN} New Identity. + * + * NOTES + * Memory for the identity is allocated inside the function, and all + * internal identity elements as well. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTFOUND Identity not found. + * NZERROR_PARMS Error in description. + */ +nzerror nztiDuplicateIdentity( nzctx *, nzttIdentity *, + nzttIdentity ** ); +#endif /* NZ_OLD_TOOLS */ + +/*--------------------- nztiAbortIdentity ---------------------*/ + +/* + * NAME + * nztiAbortIdentity - Abort an unassociated identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN/OUT} Identity. + * + * NOTES + * It is an error to try to abort an identity that can be + * referenced through a persona. + * + * The identity pointer is set to NULL at the conclusion. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_CANTABORT Identity is associated with persona. + */ +nzerror nztiAbortIdentity( nzctx *, nzttIdentity ** ); + +#ifdef NZ_OLD_TOOLS +/*----------------- nztidGetIdentityDesc -----------------*/ + +/* + * NAME + * nztidGetIdentityDesc - Gets an Identity Description from the identity + * + * PARAMETERS + * osscntxt {IN} Success. + * identity {IN} Identity. + * description {IN/OUT} Identity Description. + * + * NOTES + * Memory is allocated for the Identity Description. It + * is the callers responsibility to free this memory by calling + * nztiFreeIdentityDesc. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztidGetIdentityDesc( nzctx *, nzttIdentity *, + nzttIdentityDesc ** ); + +/*----------------- nztidFreeIdentityDesc -----------------*/ + +/* + * NAME + * nztidFreeIdentityDesc - Frees memory for Identity Desc object. + * + * PARAMETERS + * osscntxt {IN} oss context. + * description {IN/OUT} Identity Description. + * + * NOTES + * Memory is freed for all Identity description elements. Pointer is + * then set to null. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztidFreeIdentityDesc( nzctx *, nzttIdentityDesc ** ); +#endif /* NZ_OLD_TOOLS */ + +/*---------------- nztific_FreeIdentityContent ----------------*/ + +/* + * NAME + * nztific_FreeIdentityContent - free the contents of an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN/OUT} freed identity + * + * NOTES + * Free a created identity. + * + * RETURNS + * NZERROR_OK Success. + */ +/* + * Free the identity content. + */ +nzerror nztific_FreeIdentityContent( nzctx *ossctx, + nzttIdentity *identity ); + + +/*-------------------------- nztSign --------------------------*/ + +/* + * NAME + * nztSign - Create an attached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Open persona acting as signer. + * state {IN} State of signature. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztSign( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------------- nztVerify -------------------------*/ + +/* + * NAME + * nztVerify - Verify an attached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of verification. + * intdulen {IN} TDU length. + * intdu {IN} TDU. + * out {IN/OUT} Extracted message. + * verified {OUT} TRUE if signature verified. + * validated{OUT} TRUE if signing identity validated. + * identity {OUT} Identity of signing party. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow outptu buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztVerify( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock *, boolean *, boolean *, + nzttIdentity ** ); + +/*------------------------ nztValidate ------------------------*/ + +/* + * NAME + * nztValidate - Validate an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * identity {IN} Identity. + * validated{OUT} TRUE if identity was validated. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztValidate( nzctx *, nzttPersona *, nzttIdentity *, boolean * ); + +/*-------------------- nztsd_SignDetached --------------------*/ + +/* + * NAME + * nztsd_SignDetached - Generate a detached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of signature. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztsd_SignDetached( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------- nztved_VerifyDetached -------------------*/ + +/* + * NAME + * nztved_VerifyDetached - Verify a detached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of verification. + * inlen {IN} Length of data. + * in {IN} Data. + * intdulen {IN} Input TDU length. + * tdu {IN} Input TDU. + * verified {OUT} TRUE if signature verified. + * validated{OUT} TRUE if signing identity validated. + * identity {OUT} Identity of signing party. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztved_VerifyDetached( nzctx *, nzttPersona *, nzttces, ub4, + ub1 *, ub4, ub1 *, boolean *, boolean *, + nzttIdentity ** ); + +/*--------------------- nztkec_PKEncrypt ---------------------*/ + +/* + * NAME + * nztkec_PKEncrypt - Encrypt data symmetrically, encrypt key asymmetrically + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nrecipients {IN} Number of recipients for this encryption. + * recipients {IN} List of recipients. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * There is a limitation of 1 recipient (nrecipients = 1) at this + * time. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztkec_PKEncrypt( nzctx *, nzttPersona *, ub4, nzttIdentity *, + nzttces, ub4, ub1 *, nzttBufferBlock * ); + +/*---------------- nztxkec_PKEncryptExpansion ----------------*/ + +/* + * NAME + * nztxkec_PKEncryptExpansion - Determine the buffer needed for PKEncrypt + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nrecipients {IN} Number of recipients. + * inlen {IN} Length of input. + * tdulen {out} Length of buffer need. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxkec_PKEncryptExpansion( nzctx *, nzttPersona *, ub4, ub4, + ub4 * ); + +/*--------------------- nztkdc_PKDecrypt ---------------------*/ + +/* + * NAME + * nztkdc_PKDecrypt - Decrypt a PKEncrypted message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztkdc_PKDecrypt( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*-------------------------- nztHash --------------------------*/ + +/* + * NAME + * nztHash - Generate a hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of hash. + * inlen {IN} Length of this input. + * in {IN} This input. + * tdu {IN/OUT} Output tdu. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztHash( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*----------------------- nztSeedRandom -----------------------*/ + +/* + * NAME + * nztSeedRandom - Seed the random function + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * seedlen {IN} Length of seed. + * seed {IN} Seed. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztSeedRandom( nzctx *, nzttPersona *, ub4, ub1 * ); + +/*--------------------- nztrb_RandomBytes ---------------------*/ + +/* + * NAME + * nztrb_RandomBytes - Generate a buffer random bytes. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nbytes {IN} Number of bytes desired. + * out {IN/OUT} Buffer block for bytes. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztrb_RandomBytes( nzctx *, nzttPersona *, ub4, + nzttBufferBlock * ); + +/*-------------------- nztrn_RandomNumber --------------------*/ + +/* + * NAME + * nztrn_RandomNumber - Generate a random number + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * num {OUT} Number. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztrn_RandomNumber( nzctx *, nzttPersona *, uword * ); + +/*---------------------- nztbbInitBlock ----------------------*/ + +/* + * NAME + * nztbbInitBlock - Initialize a buffer block. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * block {IN/OUT} Buffer block. + * + * NOTES + * The buffer block is initialized to be empty (all members are set + * to 0/NULL). Such a block will be allocated memory as needed. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbInitBlock( nzctx *, nzttBufferBlock * ); + +/*---------------------- nztbbReuseBlock ----------------------*/ + +/* + * NAME + * nztbbReuseBlock - Reuse an already initialized and possibly used block. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * block {IN/OUT} Buffer block. + * + * NOTES + * This function simply sets the used length member of the buffer + * block to 0. If the block already has memory allocated to it, + * this will cause it to be reused. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbReuseBlock( nzctx *, nzttBufferBlock * ); + +/*---------------------- nztbbSizeBlock ----------------------*/ + +/* + * NAME + * nztbbSizeBlock - Size an initialized block to a particular size. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * len {IN} Minimum number of unused bytes desired. + * block {IN/OUT} Buffer block. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbSizeBlock( nzctx *, ub4, nzttBufferBlock * ); + +/*----------------------- nztbbGrowBlock -----------------------*/ + +/* + * NAME + * nzbbGrowBlock - Increase the size of the buffer block. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * inc {IN} Number of bytes to increase. + * block {IN/OUT} Buffer block. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbGrowBlock( nzctx *, ub4, nzttBufferBlock * ); + +/*---------------------- nztbbPurgeBlock ----------------------*/ + +/* + * NAME + * nztbbPurgeBlock - Purge a buffer block of its memory. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * block {IN/OUT} Buffer block. + * + * NOTES + * The memory used by the buffer block as the buffer is released. + * The buffer block itself is not affected. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbPurgeBlock( nzctx *, nzttBufferBlock * ); + +/*----------------------- nztbbSetBlock -----------------------*/ + +/* + * NAME + * nztbbSetBlock - Set a buffer block to a known state. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * flags {IN} Flags to set. + * buflen {IN} Length of buffer. + * usedlen {IN} Used length. + * buffer {IN} Buffer. + * block {IN/OUT} Buffer block + * + * NOTES + * If buflen > 0, objlen == 0, and obj == NULL, then buflen bytes + * of memory is allocated and a pointer is stored in the buffer + * block. + * + * The buffer parameter remains unchanged. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbSetBlock( nzctx *, uword, ub4, ub4, ub1 *, + nzttBufferBlock * ); + + +/*--------------------- nztiGetSecInfo ---------------------*/ + +/* + * NAME + * nztiGetSecInfo - Get some security information for SSL + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * persona {IN} persona + * dname {OUT} distinguished name of the certificate + * dnamelen {OUT} length of the distinguished name + * issuername {OUT} issuer name of the certificate + * certhash {OUT} SHA1 hash of the certificate + * certhashlen{OUT} length of the hash + * NOTES + * This function allocate memories for issuername, certhash, and dname. + * To deallocate memory for those params, you should call nztdbuf_DestroyBuf. + * RETURNS + * + */ +nzerror nztiGetSecInfo( nzctx *, nzttPersona *, text **, ub4 *, + text **, ub4 *, ub1 **, ub4 * ); + + +/*---------------------- nztiGetDName ----------------------*/ + +/* + * NAME + * nztiGetDName - Get the distinguished name for the given identity + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity need to get dname from + * dn {OUT} distinguished name + * dnlen {OUT} length of the dname + * + * NOTES + * + * RETURNS + * + */ + +nzerror nztiGetDName( nzctx *, nzttIdentity *, + text **, ub4 * ); + +/*------------------- nztiGetIssuerName -------------------*/ + +/* + * NAME + * nztiGetIssuerName - Get IssuerName for the given identity + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity need to get issuername from + * issuername {OUT} issuer's name + * issuernamelen {OUT} length of the issuer's name + * + * NOTES + * + * RETURNS + * + */ +nzerror nztiGetIssuerName( nzctx *, nzttIdentity *, + text **, ub4 * ); + + +/*-------------------- nztgch_GetCertHash --------------------*/ + +/* + * NAME + * nztgch_GetCertHash - Get SHA1 hash for the certificate of the identity + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity need to get issuername from + * certHash {OUT} certHash buffer + * hashLen {OUT} length of the certHash + * + * NOTES + * Need to call nztdbuf_DestroyBuf to deallocate memory for certHash. + * RETURNS + * + */ +nzerror nztgch_GetCertHash( nzctx *, nzttIdentity *, + ub1 **, ub4 * ); + +/*-------------------- nztdbuf_DestroyBuf --------------------*/ + +/* + * NAME + * nztdbuf_DestroyBuf - Deallocation funtions for ub1 and text buffer + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * buf {IN} Allocated buffer to be destroyed. + * + * NOTES + * + * RETURNS + * + */ +nzerror nztdbuf_DestroyBuf( nzctx *, void ** ); + + +/*----------------------- nztGetCertChain -----------------------*/ + +/* + * NAME + * nztGetCertChain - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * + * NOTES + * + * RETURNS + * + */ +nzerror nztGetCertChain( nzctx *, nzttWallet * ); + +/*----------------------- nztCompareDN -----------------------*/ + +/* + * NAME + * nztCompareDN - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * dn1 {IN} distinguished name 1 + * dn2 {IN} distinguished name 2 + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztCompareDN( nzctx *, ub1 *,ub4 , ub1 *, ub4, boolean * ); + + +#ifdef NZ_OLD_TOOLS +/*--------------------- nztIdentityAlloc ---------------------*/ + +/* + * NAME + * nztIdentityAlloc - Allocate memory for nzttIdentity context + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {OUT} nzttIdentity context + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztIdentityAlloc( nzctx *, nzttIdentity ** ); + +/*--------------------- nztIPrivateAlloc ---------------------*/ + +/* + * NAME + * nztIPrivateAlloc - Allocate memory for nzttIdentityPrivate + * + * PARAMETERS + * Name {IN/OUT} Description + * + * osscntxt {IN} OSS context. + * ipriv {OUT} identityPrivate structure + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ + +nzerror nztIPrivateAlloc( nzctx *, nzttIdentityPrivate **); + + +/*---------------------- nztIDupContent ----------------------*/ + +/* + * NAME + * nztIDupContent - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * targetIdentity{OUT} target identity + * sourceIdentity {IN} source identity + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ + +nzerror nztIDupContent( nzctx *, nzttIdentity *, nzttIdentity * ); +/*---------------------- nztIPDuplicate ----------------------*/ + +/* + * NAME + * nztIPDuplicate - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * target_ipriv {OUT} target identityPrivate + * source_ipriv {IN} source identityPrivate + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztIPDuplicate( nzctx *, nzttIdentityPrivate **, + nzttIdentityPrivate * ); + +/*--------------------- nztiDupIdentList ---------------------*/ + +/* + * NAME + * nztiDupIdentList - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * source_identities {IN} source identity list + * numIdent {OUT} number of identity in the list + * ppidentity {OUT} Target of identity + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztiDupIdentList( nzctx *, nzttIdentity *, ub4 *, + nzttIdentity ** ); + +/*--------------------- nztFreeIdentList ---------------------*/ + +/* + * NAME + * nztFreeIdentList - Free memory for a list of Identities + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity context + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztFreeIdentList( nzctx *, nzttIdentity ** ); +#endif /* NZ_OLD_TOOLS */ + +/*--------------------- nztCheckVaLidity ---------------------*/ + +/* + * NAME + * nztCheckVaLidity - Check the validity of certificate + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * start_time Start time of the certificate + * end_time End time of the certificate + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztCheckValidity( nzctx *, ub4 , ub4 ); + +/*--------------------- nztwCreateWallet ---------------------*/ + +/* + * NAME + * nztwCreateWallet - Create a new wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wrllen {IN} Length of wallet resource locator. + * wrl {IN} WRL. + * pwdlen {IN} Length of password (see notes below). + * pwd {IN} Password. + * wallet {IN/OUT} Wallet. + * + * NOTES + * It is an error to try to create a wallet that already exists. + * The previously existing wallet must be destroyed first. + * + * The wallet itself is not encrypted. Rather, all the personas in + * the wallet are encrypted under the same password. A hash of the + * password is stored in the wallet. + * + * Upon success, an empty open wallet is stored in the wallet + * parameter. + * + * RETURNS + * NZERROR_OK Sucess. + * NZERROR_TK_WALLET_EXISTS Wallet already exists. + * NZERROR_RIO_OPEN RIO could not create wallet (see trace file). + */ +nzerror nztwCreateWallet( nzctx *, ub4, text *, ub4, text *, + nzttWallet * ); + + +/*--------------------- nztwDestroyWallet ---------------------*/ + +/* + * NAME + * nztwDestroyWallet - Destroy an existing wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wrllen {IN} Length of wallet resource locator. + * wrl {IN} WRL. + * pwdlen {IN} Length of password. + * pwd {IN} Password. + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_RIO_OPEN RIO could not open wallet (see trace file). + * NZERROR_RIO_DELETE Delete failed (see trace file). + */ +nzerror nztwDestroyWallet( nzctx *, ub4, text *, ub4, text * ); + +/*--------------------- nzteStorePersona ---------------------*/ + +/* + * NAME + * nzteStorePersona - Store an open persona in a wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * wallet {IN/OUT} Wallet. + * + * NOTES + * If the open persona is not associated with any wallet (it was + * created via the nzteClosePersona function), then storing the + * persona creates that association. The wallet will also have an + * updated persona list that reflects this association. + * + * If the open persona was associated with wallet 'A' (it was + * opened via the nztwOpenWallet function), and is stored back into + * wallet 'A', then then the old persona is overwritten by the new + * persona if the password can be verified. Recall that all + * personas have a unique identity id. If that id changes then + * storing the persona will put a new persona in the wallet. + * + * If the open persona was associated with wallet 'A' and is stored + * into wallet 'B', and if wallet 'B' does not contain a persona + * with that unique identity id, then the persona will be copied + * into wallet 'B', wallet 'B''s persona list will be updated, and + * the persona structure will be updated to be associated with + * wallet 'B'. If wallet 'B' already contained the persona, it + * would be overwritten by the new persona. + * + * The persona parameter is doubly indirect so that at the + * conclusion of the function call, the pointer can be directed to + * the persona in the wallet. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_RIO_STORE Store failed (see network trace file). + */ +nzerror nzteStorePersona( nzctx *, nzttPersona **, nzttWallet * ); + +/*--------------------- nzteRemovePersona ---------------------*/ + +/* + * NAME + * nzteRemovePersona - Remove a persona from the wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * The password is verified before trying to remove the persona. + * + * If the persona is open, it is closed. The persona is removed + * from the wallet list and the persona pointer is set to NULL. + * + * A double indirect pointer to the persona is required so that the + * persona pointer can be set to NULL upon completion. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_RIO_DELETE Delete failed. + */ +nzerror nzteRemovePersona( nzctx *, nzttPersona ** ); + +/*--------------------- nzteCreatePersona ---------------------*/ + +/* + * NAME + * nzteCreatePersona - Create a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * itype {IN} Identity type. + * ctype {IN} Cipher type. + * desc {IN} Persona description. + * persona {OUT} Persona. + * + * NOTES + * The resulting persona is created in the open state, but it will + * not be associated with a wallet. + * + * The memory for the persona is allocated by the function. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_TYPE Unsupported itype/ctype combination. + * NZERROR_TK_PARMS Error in persona description. + */ +nzerror nzteCreatePersona( nzctx *, nzttVersion, nzttCipherType, + nzttPersonaDesc *, nzttPersona ** ); + + +/*----------------- nztiStoreTrustedIdentity -----------------*/ + +/* + * NAME + * nztiStoreTrustedIdentity - Store an identity into a persona. + * + * PARAMETERS + * osscntxt {IN} Success. + * identity {IN/OUT} Trusted Identity. + * persona {IN/OUT} Persona. + * + * NOTES + * The identity is not saved with the persona in the wallet until + * the persona is stored. + * + * The identity parameter is double indirect so that it can point + * into the persona at the conclusion of the call. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztiStoreTrustedIdentity( nzctx *, nzttIdentity **, + nzttPersona * ); + +/*--------------------- nzteSetProtection ---------------------*/ + +/* + * NAME + * nzteSetProtection - Set the protection type for a CE function. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * func {IN} CE function. + * tdufmt {IN} TDU Format. + * protinfo {IN} Protection information specific to this format. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PROTECTION Unsupported protection. + * NZERROR_TK_PARMS Error in protection info. + */ +nzerror nzteSetProtection( nzctx *, nzttPersona *, nzttcef, nztttdufmt, + nzttProtInfo * ); + +/*--------------------- nzteGetProtection ---------------------*/ + +/* + * NAME + * nzteGetProtection - Get the protection type for a CE function. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * func {IN} CE function. + * tdufmt {OUT} TDU format. + * protinfo {OUT} Protection information. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nzteGetProtection( nzctx *, nzttPersona *, nzttcef, nztttdufmt *, + nzttProtInfo * ); + +/*-------------------- nztiRemoveIdentity --------------------*/ + +/* + * NAME + * nztiRemoveIdentity - Remove an identity from an open persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN/OUT} Identity. + * + * NOTES + * If the persona is not stored, this identity will still be in the + * persona stored in the wallet. + * + * The identity parameter is doubly indirect so that at the + * conclusion of the function, the pointer can be set to NULL. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTFOUND Identity not found. + * NZERROR_TK_NOTOPEN Persona is not open. + */ +nzerror nztiRemoveIdentity( nzctx *, nzttIdentity ** ); + +/*----------------- nztifdn -----------------*/ + +/* + * NAME + * nztifdn - create an Identity From a Distinguished Name + * + * PARAMETERS + * osscntxt {IN} OSS context. + * length {IN} Length of the distinguished name + * distinguished_name {IN} distinguished name string + * ppidentity {OUT} created identity + * + * NOTES + * Given a distinguished name, return the identity that corresponds to it. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztifdn( nzctx *ossctx, + ub4 length, + text *distinguished_name, + nzttIdentity **ppidentity ); + +/*--------------------- nztxSignExpansion ---------------------*/ + +/* + * NAME + * nztxSignExpansion - Determine the size of the attached signature buffer. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of input. + * tdulen {OUT} Buffer needed for signature. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxSignExpansion( nzctx *, nzttPersona *, ub4, ub4 * ); + +/*--------------- nztxsd_SignDetachedExpansion ---------------*/ + +/* + * NAME + * nztxsd_SignDetachedExpansion - Determine the size of buffer needed. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of input. + * tdulen {OUT} Buffer needed for signature. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxsd_SignDetachedExpansion( nzctx *, nzttPersona *, ub4, + ub4 * ); + +/*------------------------ nztEncrypt ------------------------*/ + +/* + * NAME + * nztEncrypt - Symmetrically encrypt + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztEncrypt( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------- nztxEncryptExpansion -------------------*/ + +/* + * NAME + * nztxEncryptExpansion - Determine the size of the TDU to encrypt. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input part. + * tdulen {OUT} Length of TDU. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxEncryptExpansion( nzctx *, nzttPersona *, ub4, ub4 * ); + +/*------------------------ nztDecrypt ------------------------*/ + +/* + * NAME + * nztDecrypt - Decrypt an Encrypted message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of decryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * out {IN/OUT} Cleartext message. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztDecrypt( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------------ nztEnvelope ------------------------*/ + +/* + * NAME + * nztEnvelope - Sign and PKEncrypt a message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nrecipients {IN} Number of recipients for this encryption. + * recipients {IN} List of recipients. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztEnvelope( nzctx *, nzttPersona *, ub4, nzttIdentity *, + nzttces, ub4, ub1 *, nzttBufferBlock * ); + +/*----------------------- nztDeEnvelope -----------------------*/ + +/* + * NAME + * nztDeEnvelope - PKDecrypt and verify a message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * out {OUT} Message from TDU. + * verified {OUT} TRUE if verified. + * validated {OUT} TRUE if validated. + * sender {OUT} Identity of sender. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztDeEnvelope( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock *, boolean *, boolean *, + nzttIdentity ** ); + +/*----------------------- nztKeyedHash -----------------------*/ + +/* + * NAME + * nztKeyedHash - Generate a keyed hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of hash. + * inlen {IN} Length of this input. + * in {IN} This input. + * tdu {IN/OUT} Output tdu. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztKeyedHash( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------ nztxKeyedHashExpansion ------------------*/ + +/* + * NAME + * nztxKeyedHashExpansion - Determine the space needed for a keyed hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input. + * tdulen {OUT} TDU length. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxKeyedHashExpansion( nzctx *, nzttPersona *, ub4, + ub4 * ); + +/*--------------------- nztxHashExpansion ---------------------*/ + +/* + * NAME + * nztxHashExpansion - Determine the size of the TDU for a hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input. + * tdulen {OUT} TDU length. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxHashExpansion( nzctx *, nzttPersona *, ub4, ub4 * ); + +/*---------------- nztiae_IsAuthEnabled ----------------*/ + +/* + * NAME + * nztiae_IsAuthEnabled - Checks to see if Authentication is Enabled + * in the current Cipher Spec. + * + * PARAMETERS + * ctx {IN} Oracle SSL Context + * ncipher {IN} CipherSuite + * authEnabled {OUT} Boolean for is Auth Enabled? + * + * NOTES + * + * RETURNS + * NZERROR_OK on success. + * NZERROR_TK_INV_CIPHR_TYPE if Cipher Spec is not Recognized. + */ + +nzerror nztiae_IsAuthEnabled( nzctx *ctx, + ub2 ncipher, + boolean *authEnabled ); + +/*---------------- nztiee_IsEncrEnabled ----------------*/ +/* + * NAME + * nztiee_IsEncrEnabled - Checks to see if Encryption is Enabled + * in the current Cipher Spec. + * + * PARAMETERS + * ctx {IN} Oracle SSL Context + * ncipher {IN} CipherSuite + * EncrEnabled {OUT} Boolean for is Auth Enabled? + * + * NOTES + * + * RETURNS + * NZERROR_OK on success. + * NZERROR_TK_INV_CIPHR_TYPE if Cipher Spec is not Recognized. + */ + +nzerror nztiee_IsEncrEnabled( nzctx *ctx, + ub2 ncipher, + boolean *EncrEnabled ); + +/*---------------- nztihe_IsHashEnabled ----------------*/ +/* + * NAME + * nztihe_IsHashEnabled - Checks to see if HAshing is Enabled + * in the current Cipher Spec. + * + * PARAMETERS + * ctx {IN} Oracle SSL Context + * ncipher {IN} CipherSuite + * hashEnabled {OUT} Boolean for is Auth Enabled? + * + * NOTES + * + * RETURNS + * NZERROR_OK on success. + * NZERROR_TK_INV_CIPHR_TYPE if Cipher Spec is not Recognized. + */ + +nzerror nztihe_IsHashEnabled( nzctx *ctx, + ub2 ncipher, + boolean *hashEnabled ); + +/* + * + */ + +nzerror nztGetIssuerName( nzctx *ctx, + nzttIdentity *identity, + ub1 **issuername, + ub4 *issuernamelen ); + +nzerror nztGetSubjectName( nzctx *ctx, + nzttIdentity *identity, + ub1 **subjectname, + ub4 *subjectnamelen ); + +nzerror nztGetBase64Cert( nzctx *ctx, + nzttIdentity *identity, + ub1 **b64cert, + ub4 *b64certlen ); + +nzerror nztGetSerialNumber( nzctx *ctx, + nzttIdentity *identity, + ub1 **serialnum, + ub4 *serialnumlen ); + +nzerror nztGetValidDate( nzctx *ctx, + nzttIdentity *identity, + ub4 *startdate, + ub4 *enddate ); + +nzerror nztGetVersion( nzctx *ctx, + nzttIdentity *identity, + nzstrc *pVerStr ); + +nzerror nztGetPublicKey( nzctx *ctx, + nzttIdentity *identity, + ub1 **pubKey, + ub4 *pubKeylen ); + +nzerror nztGenericDestroy( nzctx *ctx, + ub1 **var ); + +nzerror nztSetAppDefaultLocation( nzctx *ctx, + text *, + size_t ); + +nzerror nztSearchNZDefault( nzctx *ctx, + boolean *search ); + +nzerror nztSetLightWeight(nzctx *ctx, + boolean flag); + +#endif /* NZT_ORACLE */ + diff --git a/OCI/include/occi.h b/OCI/include/occi.h new file mode 100644 index 0000000..2dca9e6 --- /dev/null +++ b/OCI/include/occi.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2000, 2002, Oracle Corporation. All rights reserved. */ + +/* + NAME + occi.h - Oracle C++ Interface header files. + + DESCRIPTION + + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + vvinay 08/19/02 - + aahluwal 06/03/02 - bug 2360115 + gayyappa 01/03/01 - removed inclusions before occiCommon.h + kmohan 04/11/00 - include oci.h and occiCommon.h also + rkasamse 04/03/00 - header file for all the OCCI classes + rkasamse 04/03/00 - Creation + +*/ + +#ifndef OCCI_ORACLE +# define OCCI_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +#ifndef OCCIDATA_ORACLE +#include +#endif + +#ifndef OCCICONTROL_ORACLE +#include +#endif + +#ifndef OCCIOBJECTS_ORACLE +#include +#endif + +#ifndef OCCIAQ_ORACLE +#include +#endif + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCCI_ORACLE */ diff --git a/OCI/include/occiAQ.h b/OCI/include/occiAQ.h new file mode 100644 index 0000000..e07e40c --- /dev/null +++ b/OCI/include/occiAQ.h @@ -0,0 +1,374 @@ +/* Copyright (c) 2002, 2005, Oracle. All rights reserved. */ + +/* + NAME + occiAQ.h - Header file for occi AQ classes + + DESCRIPTION + Class declarations for Producer, Consumer, Message, Agent + Listener, Subscription + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + cparampa 10/12/02 - creation + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCIAQ_ORACLE +# define OCCIAQ_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +namespace oracle { +namespace occi { +namespace aq{ + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +class Message +{ + public: + + enum MessageState + { + MSG_READY = OCI_MSG_READY, + MSG_WAITING = OCI_MSG_WAITING, + MSG_PROCESSED = OCI_MSG_PROCESSED, + MSG_EXPIRED = OCI_MSG_EXPIRED + }; + enum PayloadType + { + RAW, + ANYDATA, + OBJECT + }; + + Message( const Environment *env ); + Message( const Message& rhs); + ~Message(); + + void operator=(const Message& rhs); + int getAttemptsToDequeue() const ; + void setCorrelationId( const OCCI_STD_NAMESPACE::string& corr_id ) ; + OCCI_STD_NAMESPACE::string getCorrelationId() const ; + void setDelay( int delay ) ; + int getDelay() const ; + Date getMessageEnqueuedTime() const ; + void setExceptionQueueName( const OCCI_STD_NAMESPACE::string& queue ) ; + OCCI_STD_NAMESPACE::string getExceptionQueueName() const ; + void setExpiration( int exp ) ; + int getExpiration() const ; + MessageState getMessageState() const ; + void setPriority( int priority ) ; + int getPriority() const ; + void setRecipientList( OCCI_STD_NAMESPACE::vector& ag_list ) ; + void setSenderId( const Agent& sender ) ; + Agent getSenderId() const ; + void setOriginalMessageId( const Bytes& queue ) ; + Bytes getOriginalMessageId() const ; + void setNull(); + bool isNull() const; + + void setBytes( const Bytes& bytes); + void setObject( PObject* pobj); + void setAnyData( const AnyData& any); + + Bytes getBytes() const ; + PObject *getObject() ; + AnyData getAnyData() const ; + + PayloadType getPayloadType( ) const; + + private: + Ptr ptr; + OCIAQMsgProperties* getOCIMsgProperties() const; + Message( const Environment *env, const Connection *con, + OCIAQMsgProperties *msgprop, void *data, unsigned int dataLen, + bool isNull, PayloadType pType); + friend class ConsumerImpl; + friend class ProducerImpl; + friend class NotifyResult; +}; + +class Producer +{ + public: + + enum EnqueueSequence + { + ENQ_BEFORE = OCI_ENQ_BEFORE, + ENQ_TOP = OCI_ENQ_TOP + }; + enum Visibility + { + ENQ_IMMEDIATE = OCI_ENQ_IMMEDIATE, + ENQ_ON_COMMIT = OCI_ENQ_ON_COMMIT + }; + + Producer( const Connection *conn ); + Producer( const Connection *conn, + const OCCI_STD_NAMESPACE::string& queue ); + Producer( const Producer& rhs); + ~Producer(); + + void operator=(const Producer& prod); + void setRelativeMessageId( const Bytes& msgid ); + Bytes getRelativeMessageId() const; + void setSequenceDeviation( EnqueueSequence option ); + EnqueueSequence getSequenceDeviation() const; + void setVisibility( Visibility option ); + Visibility getVisibility() const; + void setQueueName( const OCCI_STD_NAMESPACE::string& queue ); + OCCI_STD_NAMESPACE::string getQueueName() const; + void setTransformation( const OCCI_STD_NAMESPACE::string& fName); + OCCI_STD_NAMESPACE::string getTransformation() const; + Bytes send( Message& msg, const OCCI_STD_NAMESPACE::string& queue ); + Bytes send( Message& msg ); + void setNull(); + bool isNull() const; + + private: + Ptr ptr; +}; + +class Consumer +{ + public: + + enum DequeueMode + { + DEQ_BROWSE = OCI_DEQ_BROWSE, + DEQ_LOCKED = OCI_DEQ_LOCKED, + DEQ_REMOVE = OCI_DEQ_REMOVE, + DEQ_REMOVE_NODATA = OCI_DEQ_REMOVE_NODATA + }; + enum Navigation + { + DEQ_FIRST_MSG = OCI_DEQ_FIRST_MSG, + DEQ_NEXT_TRANSACTION = OCI_DEQ_NEXT_TRANSACTION, + DEQ_NEXT_MSG = OCI_DEQ_NEXT_MSG + }; + enum Visibility + { + DEQ_IMMEDIATE = OCI_DEQ_IMMEDIATE, + DEQ_ON_COMMIT = OCI_DEQ_ON_COMMIT + }; + enum + { + DEQ_WAIT_FOREVER = OCI_DEQ_WAIT_FOREVER, + DEQ_NO_WAIT = OCI_DEQ_NO_WAIT + }; + + Consumer( const Connection *conn ); + Consumer( const Connection * conn, const Agent& agent); + Consumer( const Connection *conn, + const OCCI_STD_NAMESPACE::string& queue ); + Consumer(const Consumer& con); + ~Consumer(); + + void operator=(const Consumer& con); + void setAgent(const Agent& agent); + void setConsumerName( const OCCI_STD_NAMESPACE::string& name ); + OCCI_STD_NAMESPACE::string getConsumerName() const; + void setCorrelationId( const OCCI_STD_NAMESPACE::string& cor_id ); + OCCI_STD_NAMESPACE::string getCorrelationId() const; + void setDequeueMode( DequeueMode mode ); + DequeueMode getDequeueMode() const; + void setMessageIdToDequeue( const Bytes& msgid ); + Bytes getMessageIdToDequeue() const; + void setPositionOfMessage( Navigation pos ); + Navigation getPositionOfMessage() const; + void setVisibility( Visibility option ); + Visibility getVisibility() const; + void setWaitTime( unsigned int wait ); + unsigned int getWaitTime() const; + void setQueueName( const OCCI_STD_NAMESPACE::string& queue ); + OCCI_STD_NAMESPACE::string getQueueName() const; + void setTransformation( const OCCI_STD_NAMESPACE::string& fName); + OCCI_STD_NAMESPACE::string getTransformation() const; + Message receive( Message::PayloadType pType, + const OCCI_STD_NAMESPACE::string& type="", + const OCCI_STD_NAMESPACE::string& schema=""); + void setNull(); + bool isNull() const; + + private: + Ptr ptr; +}; + +class Agent +{ + public: + Agent( const Environment *env ); + Agent( const Environment *env, + const OCCI_STD_NAMESPACE::string& name, + const OCCI_STD_NAMESPACE::string& address, + unsigned int protocol=0 ) ; + Agent(const Agent& a); + ~Agent() ; + + void operator=(const Agent& a); + void setName( const OCCI_STD_NAMESPACE::string& name ); + OCCI_STD_NAMESPACE::string getName() const; + void setAddress( const OCCI_STD_NAMESPACE::string& addr ); + OCCI_STD_NAMESPACE::string getAddress() const; + void setProtocol(unsigned int protocol = 0); + unsigned int getProtocol() const; + void setNull(); + bool isNull() const; + OCIAQAgent* getOCIAQAgent() const; + + private: + Ptr ptr; + Agent( const Environment *env, OCIAQAgent *rhs, bool toFree = false ); + friend class Listener; + friend class MessageImpl; +}; + +class Listener +{ + public: + Listener( const Connection *conn ); + Listener( const Connection *conn, + OCCI_STD_NAMESPACE::vector &agList, + int waitTime=0 ); + ~Listener(); + + Agent listen(); + void setAgentList(OCCI_STD_NAMESPACE::vector &agList); + void setTimeOutForListen(int waitTime); + OCCI_STD_NAMESPACE::vector getAgentList() const; + int getTimeOutForListen() const; + + private: + const ConnectionImpl *conn; + OCIAQAgent** agentList; + unsigned int numAgents; + int timeOut; + void *listenerExt; +}; + + +class Subscription +{ + public: + enum Presentation + { + PRES_DEFAULT = OCI_SUBSCR_PRES_DEFAULT, + PRES_XML = OCI_SUBSCR_PRES_XML + }; + enum Protocol + { + PROTO_CBK = OCI_SUBSCR_PROTO_OCI, + PROTO_MAIL = OCI_SUBSCR_PROTO_MAIL, + PROTO_SERVER = OCI_SUBSCR_PROTO_SERVER, + PROTO_HTTP = OCI_SUBSCR_PROTO_HTTP + }; + enum Namespace + { + NS_ANONYMOUS = OCI_SUBSCR_NAMESPACE_ANONYMOUS, + NS_AQ = OCI_SUBSCR_NAMESPACE_AQ + }; + + Subscription(const Environment* env); + Subscription(const Environment* env, OCISubscription* sub); + Subscription(const Subscription& sub); + ~Subscription(); + + void operator=(const Subscription& sub); + unsigned int getDatabaseServersCount() const; + void setDatabaseServerNames( + const OCCI_STD_NAMESPACE::vector& dbsrv); + OCCI_STD_NAMESPACE::vector + getDatabaseServerNames() const ; + void setNotifyCallback(unsigned int (*callback)(Subscription& sub, + NotifyResult *nr)); + unsigned int (*getNotifyCallback() const)(Subscription& sub, + NotifyResult *nr); + void setCallbackContext(void* ctx); + void* getCallbackContext() const; + void setSubscriptionName(const OCCI_STD_NAMESPACE::string& name); + OCCI_STD_NAMESPACE::string getSubscriptionName() const ; + void setSubscriptionNamespace(Namespace nameSpace); + Namespace getSubscriptionNamespace() const ; + void setPayload(const Bytes& payload); + Bytes getPayload() const ; + void setRecipientName( const OCCI_STD_NAMESPACE::string& name); + OCCI_STD_NAMESPACE::string getRecipientName() const; + void setPresentation( Presentation pres) ; + Presentation getPresentation() const ; + void setProtocol( Protocol prot) ; + Protocol getProtocol() const ; + OCISubscription* getOCISubscription() const; + void setNull(); + bool isNull() const; + Environment* getEnvironment() const; + + private: + Ptr ptr; +}; + +class NotifyResult +{ + public: + Bytes getPayload() const; + Message getMessage() const; + Bytes getMessageId() const; + OCCI_STD_NAMESPACE::string getConsumerName() const; + OCCI_STD_NAMESPACE::string getQueueName() const; + + private: + const EnvironmentImpl *env; + void *payload; + unsigned int payloadLen; + void *desc; + ub4 mode; + void *notifyResultExt; + + //private constructor + NotifyResult(const Environment *env, void *payload, ub4 payloadLen, + void *pdescriptor, ub4 mode); + + friend class SubscriptionImpl; +}; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ +} /* end of namespace aq */ +} /* end of namespace occi */ +} /* end of namespace oracle */ + +#endif /* OCCIAQ_ORACLE */ + +#endif /* _olint */ diff --git a/OCI/include/occiCommon.h b/OCI/include/occiCommon.h new file mode 100644 index 0000000..5485ff0 --- /dev/null +++ b/OCI/include/occiCommon.h @@ -0,0 +1,982 @@ +/* Copyright (c) 2000, 2008, Oracle. All rights reserved. */ + +/* + NAME + occiCommon.h - header file for doing forward references + + DESCRIPTION + Just declare all the classes + + RELATED DOCUMENTS + OCCI Programmer's Guide + + EXPORT FUNCTION(S) + none + + INTERNAL FUNCTION(S) + none + + EXAMPLES + + NOTES + none + +*/ + + +#ifndef OCCICOMMON_ORACLE +# define OCCICOMMON_ORACLE + +#ifndef _olint + +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORASTRINGSTL +#define ORASTRINGSTL +#include +#endif + +#ifndef ORAVECTORSTL +#include +#define ORAVECTORSTL +#endif + +#ifndef ORALISTSTL +#include +#define ORALISTSTL +#endif + +#define OCCI_STD_NAMESPACE std +#define OCCI_HAVE_STD_NAMESPACE 1 + +// version definitions +#define OCCI_MAJOR_VERSION OCI_MAJOR_VERSION +#define OCCI_MINOR_VERSION OCI_MINOR_VERSION + +namespace oracle { +namespace occi { + +//UString is the class for UTF16 characterset +//check for version = 3.2 or 3.3 +#if (__GNUC__ == 3 && (__GNUC_MINOR__ == 2 || __GNUC_MINOR__ == 3)) + //char_traits specialization for utext for gcc 3.2.3 + struct utext_char_traits + { + typedef utext char_type; + typedef unsigned int int_type; + + typedef OCCI_STD_NAMESPACE::streampos pos_type; + typedef OCCI_STD_NAMESPACE::streamoff off_type; + typedef OCCI_STD_NAMESPACE::mbstate_t state_type; + + //assign one char to another + static void assign(char_type& c1, const char_type& c2) + { + c1 = c2; + } + + //are 2 chars equal ? + static bool eq(const char_type& c1, const char_type& c2) + { + return c1 == c2; + } + + //is char c1 less then c2 ? + static bool lt(const char_type& c1, const char_type& c2) + { + return c1 < c2; + } + + //compare 2 strings of char + static int compare(const char_type* s1, const char_type* s2, size_t n) + { + for (size_t i = 0; i < n; ++i) + if (!eq(s1[i], s2[i])) + return s1[i] < s2[i] ? -1 : 1; + return 0; + } + + //length of a char string + static size_t length(const char_type* s) + { + const char_type nullchar = char_type(0); + size_t i = 0; + + while (!eq(*s++, nullchar)) i++; + return i; + } + + //find a character in the char string + static const char_type* find(const char_type* s, + size_t n, const char_type& c) + { + for ( ; n > 0 ; ++s, --n) + if (eq(*s, c)) + return s; + return 0; + } + + //move n chars from s2 to s1 + static char_type* move(char_type* s1, const char_type* s2, size_t n) + { + memmove(s1, s2, n * sizeof(char_type)); + return s1; + } + + //copy n chars from s2 to s1 + static char_type* copy(char_type* s1, const char_type* s2, size_t n) + { + memcpy(s1, s2, n * sizeof(char_type)); + return s1; + } + + //fill char c into s + static char_type* assign(char_type* s, size_t n, char_type c) + { + for (size_t i = 0; i < n; ++i) + assign(s[i], c); + return s; + } + + //is the int representation eof ? + static int_type not_eof(const int_type& c) + { + if (c == eof()) + return 0; + else + return c; + } + + //cast a int type to char + static char_type to_char_type(const int_type& c) + { + return static_cast(c); + } + + //cast char to int type + static int_type to_int_type(const char_type& c) + { + return static_cast(c); + } + + //eq operator when the chars are represented as ints + static bool eq_int_type(const int_type& c1, const int_type& c2) + { + return c1 == c2; + } + + //eof character + static int_type eof() + { + return static_cast(-1); + } + + + }; //end char_traits + +typedef OCCI_STD_NAMESPACE::basic_string UString; +#else +//for non gcc 3.2.3 platforms +typedef OCCI_STD_NAMESPACE::basic_string UString; +#endif /* if gcc 3.2.3 */ + +class Environment; +class EnvironmentImpl; +class Connection; +class ConnectionImpl; +class ConnectionPool; +class ConnectionPoolImpl; +class StatelessConnectionPool; +class StatelessConnectionPoolImpl; +class Statement; +class StatementImpl; +class ResultSet; +class ResultSetImpl; +class SQLException; +class SQLExceptionImpl; +class BatchSQLException; +class BatchSQLExceptionImpl; +class Stream; +class PObject; +class Number; +class Bytes; +class BytesImpl; +class Date; +class Timestamp; + +class MetaData; +class MetaDataImpl; +template class Ref; +class RefImpl; +class RefAny; +class Blob; +class Bfile; +class Clob; +class LobStreamImpl; +class AnyData; +class AnyDataImpl; +class Map; +class IntervalDS; +class IntervalYM; + +namespace aq { +class Message; +class MessageImpl; +class Agent; +class AgentImpl; +class Producer; +class ProducerImpl; +class Consumer; +class ConsumerImpl; +class Listener; +class Subscription; +class SubscriptionImpl; +class NotifyResult; +} + +typedef struct BFloat BFloat; +typedef struct BDouble BDouble; + +/*--------------------------------------------------------------------------- + ENUMERATORS + ---------------------------------------------------------------------------*/ +enum Type +{ + OCCI_SQLT_CHR=SQLT_CHR, + OCCI_SQLT_NUM=SQLT_NUM, + OCCIINT = SQLT_INT, + OCCIFLOAT = SQLT_FLT, + OCCIBFLOAT = SQLT_BFLOAT, + OCCIBDOUBLE = SQLT_BDOUBLE, + OCCIIBFLOAT = SQLT_IBFLOAT, + OCCIIBDOUBLE = SQLT_IBDOUBLE, + OCCI_SQLT_STR=SQLT_STR, + OCCI_SQLT_VNU=SQLT_VNU, + OCCI_SQLT_PDN=SQLT_PDN, + OCCI_SQLT_LNG=SQLT_LNG, + OCCI_SQLT_VCS=SQLT_VCS, + OCCI_SQLT_NON=SQLT_NON, + OCCI_SQLT_RID=SQLT_RID, + OCCI_SQLT_DAT=SQLT_DAT, + OCCI_SQLT_VBI=SQLT_VBI, + OCCI_SQLT_BIN=SQLT_BIN, + OCCI_SQLT_LBI=SQLT_LBI, + OCCIUNSIGNED_INT = SQLT_UIN, + OCCI_SQLT_SLS=SQLT_SLS, + OCCI_SQLT_LVC=SQLT_LVC, + OCCI_SQLT_LVB=SQLT_LVB, + OCCI_SQLT_AFC=SQLT_AFC, + OCCI_SQLT_AVC=SQLT_AVC, + OCCI_SQLT_CUR=SQLT_CUR, + OCCI_SQLT_RDD=SQLT_RDD, + OCCI_SQLT_LAB=SQLT_LAB, + OCCI_SQLT_OSL=SQLT_OSL, + OCCI_SQLT_NTY=SQLT_NTY, + OCCI_SQLT_REF=SQLT_REF, + OCCI_SQLT_CLOB=SQLT_CLOB, + OCCI_SQLT_BLOB=SQLT_BLOB, + OCCI_SQLT_BFILEE=SQLT_BFILEE, + OCCI_SQLT_CFILEE=SQLT_CFILEE, + OCCI_SQLT_RSET=SQLT_RSET, + OCCI_SQLT_NCO=SQLT_NCO, + OCCI_SQLT_VST=SQLT_VST, + OCCI_SQLT_ODT=SQLT_ODT, + OCCI_SQLT_DATE=SQLT_DATE, + OCCI_SQLT_TIME=SQLT_TIME, + OCCI_SQLT_TIME_TZ=SQLT_TIME_TZ, + OCCI_SQLT_TIMESTAMP=SQLT_TIMESTAMP, + OCCI_SQLT_TIMESTAMP_TZ=SQLT_TIMESTAMP_TZ, + OCCI_SQLT_INTERVAL_YM=SQLT_INTERVAL_YM, + OCCI_SQLT_INTERVAL_DS=SQLT_INTERVAL_DS, + OCCI_SQLT_TIMESTAMP_LTZ=SQLT_TIMESTAMP_LTZ, + OCCI_SQLT_FILE=SQLT_FILE, + OCCI_SQLT_CFILE=SQLT_CFILE, + OCCI_SQLT_BFILE=SQLT_BFILE, + + OCCICHAR = 32 *1024, + OCCIDOUBLE, + OCCIBOOL, + OCCIANYDATA , + OCCINUMBER, + OCCIBLOB, + OCCIBFILE, + OCCIBYTES, + OCCICLOB , + OCCIVECTOR, + OCCIMETADATA, + OCCIPOBJECT, + OCCIREF , + OCCIREFANY, + OCCISTRING , + OCCISTREAM , + OCCIDATE , + OCCIINTERVALDS , + OCCIINTERVALYM , + OCCITIMESTAMP, + OCCIROWID, + OCCICURSOR + + +}; + +enum LockOptions {OCCI_LOCK_NONE = OCI_LOCK_NONE, + OCCI_LOCK_X = OCI_LOCK_X, + OCCI_LOCK_X_NOWAIT = OCI_LOCK_X_NOWAIT + }; + +enum {OCCI_MAX_PREFETCH_DEPTH = UB4MAXVAL}; + +enum TypeCode +{ + +OCCI_TYPECODE_REF = OCI_TYPECODE_REF, +OCCI_TYPECODE_DATE = OCI_TYPECODE_DATE, +OCCI_TYPECODE_REAL = OCI_TYPECODE_REAL, +OCCI_TYPECODE_DOUBLE = OCI_TYPECODE_DOUBLE, +OCCI_TYPECODE_BDOUBLE = OCI_TYPECODE_BDOUBLE, +OCCI_TYPECODE_FLOAT = OCI_TYPECODE_FLOAT, +OCCI_TYPECODE_BFLOAT = OCI_TYPECODE_BFLOAT, +OCCI_TYPECODE_NUMBER = OCI_TYPECODE_NUMBER, +OCCI_TYPECODE_DECIMAL = OCI_TYPECODE_DECIMAL, +OCCI_TYPECODE_OCTET = OCI_TYPECODE_OCTET, +OCCI_TYPECODE_INTEGER = OCI_TYPECODE_INTEGER, +OCCI_TYPECODE_SMALLINT= OCI_TYPECODE_SMALLINT, +OCCI_TYPECODE_RAW = OCI_TYPECODE_RAW, +OCCI_TYPECODE_VARCHAR2 = OCI_TYPECODE_VARCHAR2, +OCCI_TYPECODE_VARCHAR = OCI_TYPECODE_VARCHAR, +OCCI_TYPECODE_CHAR = OCI_TYPECODE_CHAR, +OCCI_TYPECODE_VARRAY= OCI_TYPECODE_VARRAY, +OCCI_TYPECODE_TABLE = OCI_TYPECODE_TABLE, +OCCI_TYPECODE_CLOB = OCI_TYPECODE_CLOB, +OCCI_TYPECODE_BLOB = OCI_TYPECODE_BLOB, +OCCI_TYPECODE_BFILE = OCI_TYPECODE_BFILE, +OCCI_TYPECODE_OBJECT = OCI_TYPECODE_OBJECT, +OCCI_TYPECODE_NAMEDCOLLECTION = OCI_TYPECODE_NAMEDCOLLECTION +}; + +enum CharSetForm +{ + OCCI_SQLCS_IMPLICIT = SQLCS_IMPLICIT // use local db char set + ,OCCI_SQLCS_NCHAR = SQLCS_NCHAR // use local db nchar set + ,OCCI_SQLCS_EXPLICIT = SQLCS_EXPLICIT // char set explicitly specified + ,OCCI_SQLCS_FLEXIBLE = SQLCS_FLEXIBLE // pl/sql flexible parameter +}; + +enum LobOpenMode +{ OCCI_LOB_READONLY = OCI_LOB_READONLY + ,OCCI_LOB_READWRITE = OCI_LOB_READWRITE + ,OCCI_LOB_WRITEONLY = OCI_LOB_WRITEONLY + ,OCCI_LOB_APPENDONLY = OCI_LOB_APPENDONLY + ,OCCI_LOB_FULLOVERWRITE = OCI_LOB_FULLOVERWRITE + ,OCCI_LOB_FULLREAD = OCI_LOB_FULLREAD +}; + +enum LobOptionType +{ + OCCI_LOB_OPT_NONE = 0, + OCCI_LOB_OPT_COMPRESS = OCI_LOB_OPT_COMPRESS, + OCCI_LOB_OPT_ENCRYPT = OCI_LOB_OPT_ENCRYPT, + OCCI_LOB_OPT_DEDUPLICATE = OCI_LOB_OPT_DEDUPLICATE, + OCCI_LOB_OPT_ALLOCSIZE = OCI_LOB_OPT_ALLOCSIZE, + OCCI_LOB_OPT_CONTENTTYPE = OCI_LOB_OPT_CONTENTTYPE, + OCCI_LOB_OPT_MODTIME = OCI_LOB_OPT_MODTIME +}; + +enum LobOptionValue +{ + // Compression Options + OCCI_LOB_COMPRESS_OFF = OCI_LOB_COMPRESS_OFF, + OCCI_LOB_COMPRESS_ON = OCI_LOB_COMPRESS_ON, + // Encryption Options + OCCI_LOB_ENCRYPT_OFF = OCI_LOB_ENCRYPT_OFF, + OCCI_LOB_ENCRYPT_ON = OCI_LOB_ENCRYPT_ON, + // Sharing Options + OCCI_LOB_DEDUPLICATE_OFF = OCI_LOB_DEDUPLICATE_OFF, + OCCI_LOB_DEDUPLICATE_ON = OCI_LOB_DEDUPLICATE_ON +}; + +class RefCounted { +public: + RefCounted(); + virtual ~RefCounted(){} + const RefCounted * newRef() const; + void deleteRef() const; + +private: + + void onZeroReferences(); + unsigned long references_; + }; + +template +class ConstPtr +{ + +public: + +ConstPtr( const T* ptr = 0 ); +ConstPtr( const ConstPtr& mp ); +~ConstPtr(); +const T * operator->() const; +const T* rawPtr() const; + +#ifdef MEMBER_TEMPLATE +template operator ConstPtr(); +#endif + +protected: + +void operator=( const ConstPtr& mp ); +const T* rawPtr_; + +}; + +template +class Ptr : public ConstPtr { + +public: + +Ptr( T* ptr = 0 ); +Ptr( const Ptr& mp ); +void operator=( const Ptr& mp ); +const T * operator->() const; +T * operator->(); +T* rawPtr() ; +const T* rawPtr() const; + + + +#ifdef MEMBER_TEMPLATE + template + operator Ptr(); +#endif + +}; + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + template + void getVectorOfRefs( const AnyData &any, + OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)); + #else + template + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)); + #endif + + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + template + void setVectorOfRefs( AnyData &any, + const OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector< T > &vect) ; + #else + template + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector< T* > &vect) ; + #endif + + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ;//UTF16 support + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + template + void getVectorOfRefs(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T > &vect) ; + #else + template + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T* > &vect) ; + #endif + + + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ;//UTF16 support + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + template + void getVectorOfRefs(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T > &vect) ; + #else + template + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T* > &vect) ; + #endif + + + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype); + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + template + void setVectorOfRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector< T > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #else + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #endif + +/* ------------------------------------------------------------------------ + Statement setVector functions, schema & type separate + arguments - multibyte support + ------------------------------------------------------------------------ +*/ + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName); + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + template + void setVectorOfRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + #endif + + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector< T > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + #else + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, const OCCI_STD_NAMESPACE::string + &schemaName, const OCCI_STD_NAMESPACE::string &typeName) ; + #endif + +/*------------------------------------------------------------------------- + Statement setVector function - UTF16 support + ------------------------------------------------------------------------- +*/ + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName); + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + template + void setVectorOfRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const UString &schemaName, + const UString &typeName) ; + + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const UString &schemaName, + const UString &typeName) ; + #endif + + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector< T > &vect, + const UString &schemaName, + const UString &typeName) ; + #else + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, const UString + &schemaName, const UString &typeName) ; + #endif + + +/* Global method for array pins */ +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +OCCI_STD_NAMESPACE::vector &vectObj, +LockOptions lockOpt = OCCI_LOCK_NONE ); + +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +LockOptions lockOpt = OCCI_LOCK_NONE ); + +#ifdef ORAXB8_DEFINED + void readVectorOfBfiles(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + + void readVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + void writeVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + + void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); + void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); +#endif + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +} /* end of namespace occi */ +} /* end of namespace oracle */ + + +#endif /* _olint */ + +#endif /* OCCICOMMON_ORACLE */ diff --git a/OCI/include/occiControl.h b/OCI/include/occiControl.h new file mode 100644 index 0000000..392f057 --- /dev/null +++ b/OCI/include/occiControl.h @@ -0,0 +1,2137 @@ +/* Copyright Oracle Corporation 2000, 2006. All Rights Reserved. */ + +/* + NAME + occiControl.h - header file for OCCI control classes + + DESCRIPTION + Class definitions for MetaData,SQLException,Environment, + Connection,Statement, ConnectionPool, StatelessConnectionPool + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCICONTROL_ORACLE +# define OCCICONTROL_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +#ifndef ORAEXCEPTION +#define ORAEXCEPTION +#include +#endif + +namespace oracle { +namespace occi { +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +class MetaData +{ + public : + + enum AttrId + {ATTR_PTYPE = OCI_ATTR_PTYPE, + ATTR_TIMESTAMP = OCI_ATTR_TIMESTAMP, + ATTR_OBJ_ID = OCI_ATTR_OBJ_ID, + ATTR_OBJ_NAME = OCI_ATTR_OBJ_NAME, + ATTR_OBJ_SCHEMA = OCI_ATTR_OBJ_SCHEMA, + ATTR_OBJID = OCI_ATTR_OBJID, + ATTR_NUM_COLS = OCI_ATTR_NUM_COLS, + ATTR_LIST_COLUMNS = OCI_ATTR_LIST_COLUMNS, + ATTR_REF_TDO = OCI_ATTR_REF_TDO, + ATTR_IS_TEMPORARY = OCI_ATTR_IS_TEMPORARY, + ATTR_IS_TYPED = OCI_ATTR_IS_TYPED, + ATTR_DURATION = OCI_ATTR_DURATION, + ATTR_COLLECTION_ELEMENT = OCI_ATTR_COLLECTION_ELEMENT, + ATTR_RDBA = OCI_ATTR_RDBA, + ATTR_TABLESPACE = OCI_ATTR_TABLESPACE, + ATTR_CLUSTERED = OCI_ATTR_CLUSTERED, + ATTR_PARTITIONED = OCI_ATTR_PARTITIONED, + ATTR_INDEX_ONLY = OCI_ATTR_INDEX_ONLY, + ATTR_LIST_ARGUMENTS = OCI_ATTR_LIST_ARGUMENTS, + ATTR_IS_INVOKER_RIGHTS = OCI_ATTR_IS_INVOKER_RIGHTS, + ATTR_LIST_SUBPROGRAMS = OCI_ATTR_LIST_SUBPROGRAMS, + ATTR_NAME = OCI_ATTR_NAME, + ATTR_OVERLOAD_ID = OCI_ATTR_OVERLOAD_ID, + ATTR_TYPECODE = OCI_ATTR_TYPECODE, + ATTR_COLLECTION_TYPECODE = OCI_ATTR_COLLECTION_TYPECODE, + ATTR_VERSION = OCI_ATTR_VERSION, + ATTR_IS_INCOMPLETE_TYPE = OCI_ATTR_IS_INCOMPLETE_TYPE, + ATTR_IS_SYSTEM_TYPE = OCI_ATTR_IS_SYSTEM_TYPE, + ATTR_IS_PREDEFINED_TYPE = OCI_ATTR_IS_PREDEFINED_TYPE, + ATTR_IS_TRANSIENT_TYPE = OCI_ATTR_IS_TRANSIENT_TYPE, + ATTR_IS_SYSTEM_GENERATED_TYPE = + OCI_ATTR_IS_SYSTEM_GENERATED_TYPE, + ATTR_HAS_NESTED_TABLE = OCI_ATTR_HAS_NESTED_TABLE, + ATTR_HAS_LOB = OCI_ATTR_HAS_LOB, + ATTR_HAS_FILE = OCI_ATTR_HAS_FILE, + ATTR_NUM_TYPE_ATTRS = OCI_ATTR_NUM_TYPE_ATTRS, + ATTR_LIST_TYPE_ATTRS = OCI_ATTR_LIST_TYPE_ATTRS, + ATTR_NUM_TYPE_METHODS = OCI_ATTR_NUM_TYPE_METHODS, + ATTR_LIST_TYPE_METHODS = OCI_ATTR_LIST_TYPE_METHODS, + ATTR_MAP_METHOD = OCI_ATTR_MAP_METHOD, + ATTR_ORDER_METHOD = OCI_ATTR_ORDER_METHOD, + ATTR_DATA_SIZE = OCI_ATTR_DATA_SIZE, + ATTR_DATA_TYPE = OCI_ATTR_DATA_TYPE, + ATTR_PRECISION = OCI_ATTR_PRECISION, + ATTR_SCALE = OCI_ATTR_SCALE, + ATTR_TYPE_NAME = OCI_ATTR_TYPE_NAME, + ATTR_SCHEMA_NAME = OCI_ATTR_SCHEMA_NAME, + ATTR_CHARSET_ID = OCI_ATTR_CHARSET_ID, + ATTR_CHARSET_FORM = OCI_ATTR_CHARSET_FORM, + ATTR_ENCAPSULATION = OCI_ATTR_ENCAPSULATION, + ATTR_IS_CONSTRUCTOR = OCI_ATTR_IS_CONSTRUCTOR, + ATTR_IS_DESTRUCTOR = OCI_ATTR_IS_DESTRUCTOR, + ATTR_IS_OPERATOR = OCI_ATTR_IS_OPERATOR, + ATTR_IS_SELFISH = OCI_ATTR_IS_SELFISH, + ATTR_IS_MAP = OCI_ATTR_IS_MAP, + ATTR_IS_ORDER = OCI_ATTR_IS_ORDER, + ATTR_IS_RNDS = OCI_ATTR_IS_RNDS, + ATTR_IS_RNPS = OCI_ATTR_IS_RNPS, + ATTR_IS_WNDS = OCI_ATTR_IS_WNDS, + ATTR_IS_WNPS = OCI_ATTR_IS_WNPS, + ATTR_NUM_ELEMS = OCI_ATTR_NUM_ELEMS, + ATTR_LINK = OCI_ATTR_LINK, + ATTR_MIN = OCI_ATTR_MIN, + ATTR_MAX = OCI_ATTR_MAX, + ATTR_INCR = OCI_ATTR_INCR, + ATTR_CACHE = OCI_ATTR_CACHE, + ATTR_ORDER = OCI_ATTR_ORDER, + ATTR_HW_MARK = OCI_ATTR_HW_MARK, + ATTR_IS_NULL = OCI_ATTR_IS_NULL, + ATTR_POSITION = OCI_ATTR_POSITION, + ATTR_HAS_DEFAULT = OCI_ATTR_HAS_DEFAULT, + ATTR_LEVEL = OCI_ATTR_LEVEL, + ATTR_IOMODE = OCI_ATTR_IOMODE, + ATTR_RADIX = OCI_ATTR_RADIX, + ATTR_SUB_NAME = OCI_ATTR_SUB_NAME, + ATTR_LIST_OBJECTS = OCI_ATTR_LIST_OBJECTS, + ATTR_NCHARSET_ID = OCI_ATTR_NCHARSET_ID, + ATTR_LIST_SCHEMAS = OCI_ATTR_LIST_SCHEMAS, + ATTR_MAX_PROC_LEN = OCI_ATTR_MAX_PROC_LEN, + ATTR_MAX_COLUMN_LEN = OCI_ATTR_MAX_COLUMN_LEN, + ATTR_CURSOR_COMMIT_BEHAVIOR = + OCI_ATTR_CURSOR_COMMIT_BEHAVIOR, + ATTR_MAX_CATALOG_NAMELEN = OCI_ATTR_MAX_CATALOG_NAMELEN, + ATTR_CATALOG_LOCATION = OCI_ATTR_CATALOG_LOCATION, + ATTR_SAVEPOINT_SUPPORT = OCI_ATTR_SAVEPOINT_SUPPORT, + ATTR_NOWAIT_SUPPORT = OCI_ATTR_NOWAIT_SUPPORT, + ATTR_AUTOCOMMIT_DDL = OCI_ATTR_AUTOCOMMIT_DDL, + ATTR_LOCKING_MODE = OCI_ATTR_LOCKING_MODE, + ATTR_IS_FINAL_TYPE = OCI_ATTR_IS_FINAL_TYPE, + ATTR_IS_INSTANTIABLE_TYPE = OCI_ATTR_IS_INSTANTIABLE_TYPE, + ATTR_IS_SUBTYPE = OCI_ATTR_IS_SUBTYPE, + ATTR_SUPERTYPE_SCHEMA_NAME = OCI_ATTR_SUPERTYPE_SCHEMA_NAME, + ATTR_SUPERTYPE_NAME = OCI_ATTR_SUPERTYPE_NAME, + ATTR_FSPRECISION = OCI_ATTR_FSPRECISION, + ATTR_LFPRECISION = OCI_ATTR_LFPRECISION, + ATTR_IS_FINAL_METHOD = OCI_ATTR_IS_FINAL_METHOD, + ATTR_IS_INSTANTIABLE_METHOD = OCI_ATTR_IS_INSTANTIABLE_METHOD, + ATTR_IS_OVERRIDING_METHOD = OCI_ATTR_IS_OVERRIDING_METHOD, + ATTR_CHAR_USED = OCI_ATTR_CHAR_USED, + ATTR_CHAR_SIZE = OCI_ATTR_CHAR_SIZE, + ATTR_COL_ENC = OCI_ATTR_COL_ENC, + ATTR_COL_ENC_SALT = OCI_ATTR_COL_ENC_SALT, + ATTR_TABLE_ENC = OCI_ATTR_TABLE_ENC, + ATTR_TABLE_ENC_ALG = OCI_ATTR_TABLE_ENC_ALG, + ATTR_TABLE_ENC_ALG_ID = OCI_ATTR_TABLE_ENC_ALG_ID + }; + + enum ParamType + { + PTYPE_TABLE = OCI_PTYPE_TABLE + ,PTYPE_VIEW = OCI_PTYPE_VIEW + ,PTYPE_PROC = OCI_PTYPE_PROC + ,PTYPE_FUNC = OCI_PTYPE_FUNC + ,PTYPE_PKG = OCI_PTYPE_PKG + ,PTYPE_TYPE = OCI_PTYPE_TYPE + ,PTYPE_TYPE_ATTR = OCI_PTYPE_TYPE_ATTR + ,PTYPE_TYPE_COLL = OCI_PTYPE_TYPE_COLL + ,PTYPE_TYPE_METHOD = OCI_PTYPE_TYPE_METHOD + ,PTYPE_SYN = OCI_PTYPE_SYN + ,PTYPE_SEQ = OCI_PTYPE_SEQ + ,PTYPE_COL = OCI_PTYPE_COL + ,PTYPE_ARG = OCI_PTYPE_ARG + ,PTYPE_TYPE_ARG = OCI_PTYPE_TYPE_ARG + ,PTYPE_TYPE_RESULT = OCI_PTYPE_TYPE_RESULT + ,PTYPE_SCHEMA = OCI_PTYPE_SCHEMA + ,PTYPE_DATABASE = OCI_PTYPE_DATABASE + ,PTYPE_UNK = OCI_PTYPE_UNK + }; + + + enum { DURATION_SESSION = OCI_DURATION_SESSION + ,DURATION_TRANS = OCI_DURATION_TRANS + ,DURATION_NULL = OCI_DURATION_NULL + ,TYPEENCAP_PRIVATE = OCI_TYPEENCAP_PRIVATE + ,TYPEENCAP_PUBLIC = OCI_TYPEENCAP_PUBLIC + ,TYPEPARAM_IN = OCI_TYPEPARAM_IN + ,TYPEPARAM_OUT = OCI_TYPEPARAM_OUT + ,TYPEPARAM_INOUT = OCI_TYPEPARAM_INOUT + ,CURSOR_OPEN = OCI_CURSOR_OPEN + ,CURSOR_CLOSED = OCI_CURSOR_CLOSED + ,CL_START = OCI_CL_START + ,CL_END = OCI_CL_END + ,SP_SUPPORTED = OCI_SP_SUPPORTED + ,SP_UNSUPPORTED = OCI_SP_UNSUPPORTED + ,NW_SUPPORTED = OCI_NW_SUPPORTED + ,NW_UNSUPPORTED = OCI_NW_UNSUPPORTED + ,AC_DDL = OCI_AC_DDL + ,NO_AC_DDL = OCI_NO_AC_DDL + ,LOCK_IMMEDIATE = OCI_LOCK_IMMEDIATE + ,LOCK_DELAYED = OCI_LOCK_DELAYED + }; + + MetaData(const MetaData &omd); + unsigned int getAttributeCount() const + ; + AttrId getAttributeId(unsigned int attributenum) const + ; + Type getAttributeType(unsigned int attributenum) const + ; + int getInt(MetaData::AttrId attrid) const + ; + bool getBoolean(MetaData::AttrId attrid) const + ; + unsigned int getUInt(MetaData::AttrId attrid) const + ; + OCCI_STD_NAMESPACE::string getString(MetaData::AttrId attrid) const + ; + UString getUString(MetaData::AttrId attrid) const + ; + Number getNumber(MetaData::AttrId attrid) const + ; + RefAny getRef(MetaData::AttrId attrid) const + ; + Timestamp getTimestamp(MetaData::AttrId attrid) const + ; + MetaData getMetaData(MetaData::AttrId attrid) const + ; + OCCI_STD_NAMESPACE::vector getVector(MetaData::AttrId attrid) + const ; + void operator =(const MetaData &omd); + + ~MetaData(); + + private: + + enum ociAttrType { OCI_UB1, + OCI_UB2, + OCI_UB4, + OCI_SB1, + OCI_WORD, + OCI_UB1_BOOL, + OCI_UB1PTR_TIMESTAMP, + OCI_UB1PTR_NUMBER, + OCI_TEXTPTR, + OCI_DVOIDPTR_PARAM, + OCI_DVOIDPTR_PARAMLIST, + OCI_OCIREFPTR, + OCI_OCIDURATION, + OCI_OCITYPECODE, + OCI_OCITYPEENCAP, + OCI_OCITYPEPARAMMODE, + OCI_OCIPRECISION + }; + + enum AttrCount {COMMON_ATTR_COUNT = 5, + TABLE_ATTR_COUNT = 15, + VIEW_ATTR_COUNT = 7, + FUNCPROC_ATTR_COUNT = 4, + PKG_ATTR_COUNT = 2, + TYP_ATTR_COUNT = 27, + TYPEATTR_ATTR_COUNT = 14, + TYPEMTHD_ATTR_COUNT = 16, + COLL_ATTR_COUNT = 12, + SYN_ATTR_COUNT = 4, + SEQ_ATTR_COUNT = 7, + COL_ATTR_COUNT = 15, + ARG_TYPARG_TYPRES_ATTR_COUNT = 20, + SCHEMA_ATTR_COUNT = 1, + DATABASE_ATTR_COUNT = 13, + UNK_ATTR_COUNT = 0 + }; + + static const AttrId commonAttrId[COMMON_ATTR_COUNT]; + static const ociAttrType commonAttrType[COMMON_ATTR_COUNT]; + static const AttrId tableAttrId[TABLE_ATTR_COUNT]; + static const ociAttrType tableAttrType[TABLE_ATTR_COUNT]; + static const AttrId viewAttrId[VIEW_ATTR_COUNT]; + static const ociAttrType viewAttrType[VIEW_ATTR_COUNT]; + static const AttrId funcprocAttrId[FUNCPROC_ATTR_COUNT]; + static const ociAttrType funcprocAttrType[FUNCPROC_ATTR_COUNT]; + static const AttrId pkgAttrId[PKG_ATTR_COUNT]; + static const ociAttrType pkgAttrType[PKG_ATTR_COUNT]; + static const AttrId typAttrId[TYP_ATTR_COUNT]; + static const ociAttrType typAttrType[TYP_ATTR_COUNT]; + static const AttrId typeattrAttrId[TYPEATTR_ATTR_COUNT]; + static const ociAttrType typeattrAttrType[TYPEATTR_ATTR_COUNT]; + static const AttrId typmethdAttrId[TYPEMTHD_ATTR_COUNT]; + static const ociAttrType typemthdAttrType[TYPEMTHD_ATTR_COUNT]; + static const AttrId collAttrId[COLL_ATTR_COUNT]; + static const ociAttrType collAttrType[COLL_ATTR_COUNT]; + static const AttrId synAttrId[SYN_ATTR_COUNT]; + static const ociAttrType synAttrType[SYN_ATTR_COUNT]; + static const AttrId seqAttrId[SEQ_ATTR_COUNT]; + static const ociAttrType seqAttrType[SEQ_ATTR_COUNT]; + static const AttrId colAttrId[COL_ATTR_COUNT]; + static const ociAttrType colAttrType[COL_ATTR_COUNT]; + static const AttrId argtargtresAttrId[ARG_TYPARG_TYPRES_ATTR_COUNT]; + static const ociAttrType argtargtresAttrType[ + ARG_TYPARG_TYPRES_ATTR_COUNT]; + static const AttrId schemaAttrId[SCHEMA_ATTR_COUNT]; + static const ociAttrType schemaAttrType[SCHEMA_ATTR_COUNT]; + static const AttrId databaseAttrId[DATABASE_ATTR_COUNT]; + static const ociAttrType databaseAttrType[DATABASE_ATTR_COUNT]; + + Ptr metaDataImplPtr; + const OCIParam* paramhp; + const ConnectionImpl* sesn; + const AttrId* attrIdArray; + const ociAttrType* attrTypeArray; + AttrCount attrCount; + + MetaData(const Connection *sessp, const OCCI_STD_NAMESPACE::string& objName, + ParamType prmtyp ) ; + MetaData(const Connection *sessp, const UString& objName, + ParamType prmtyp ) ; + MetaData(const Connection *sessp, + const RefAny& ref) ; + MetaData(const Connection *sessp, MetaDataImpl *implPtr, + OCIParam* parm) ; + MetaData(const Connection *sessp, MetaDataImpl *implPtr, + OCIParam *parm, ub1 parmTyp) ; + ub1 getParamType(OCIParam* prm) const ; + const AttrId* getAttrIdArrayAddr(ub1 prmTyp) const; + const ociAttrType* getAttrTypeArrayAddr(ub1 prmTyp) const; + AttrCount getAttrCount(ub1 prmTyp) const; + Type getType(ociAttrType typ) const; + bool isListTypeAttribute(AttrId attrid,ub1 ptyp) const; + boolean isInvalidAttrId(AttrId attrid,sb4* pos, + boolean* isTypeSpecificAttrPtr) const; + ociAttrType getValidAttrType(sb4 index, boolean isTypeSpecificAttr) + const; + + int getListType (const OCIParam *plist) const; + unsigned int getLowerBound(int ltype) const; + unsigned int getUpperBound(unsigned int ltype, + unsigned int paramnum) const; + friend class ConnectionImpl; + friend class ResultSetImpl; + +}; + +//return codes for user callbacks +enum +{ + OCCI_SUCCESS = OCI_SUCCESS, + FO_RETRY = OCI_FO_RETRY +}; + + +class Connection +{ + public : + + // specifies the type of proxy to be created, + // used for future enhancements + enum ProxyType + {PROXY_DEFAULT + }; + + enum FailOverType + { + FO_NONE = OCI_FO_NONE, + FO_SESSION = OCI_FO_SESSION, + FO_SELECT = OCI_FO_SELECT + }; + + enum FailOverEventType + { + FO_BEGIN = OCI_FO_BEGIN, + FO_END = OCI_FO_END, + FO_ABORT = OCI_FO_ABORT, + FO_REAUTH = OCI_FO_REAUTH, + FO_ERROR = OCI_FO_ERROR + }; + + enum Purity + { + DEFAULT = OCI_ATTR_PURITY_DEFAULT, + NEW = OCI_ATTR_PURITY_NEW, + SELF = OCI_ATTR_PURITY_SELF + }; + + virtual ~Connection() { } + virtual Statement* createStatement( + const OCCI_STD_NAMESPACE::string &sql = "") + =0; + virtual void terminateStatement(Statement *statement) =0; + virtual void commit() =0; + virtual void rollback() =0; + virtual MetaData getMetaData(const OCCI_STD_NAMESPACE::string &object, + MetaData::ParamType prmtyp + = MetaData::PTYPE_UNK) const + =0; + virtual MetaData getMetaData(const RefAny &ref) const + =0; + virtual OCCI_STD_NAMESPACE::string getClientCharSet() const + =0; + virtual OCCI_STD_NAMESPACE::string getClientNCHARCharSet() const + =0; + virtual void changePassword(const OCCI_STD_NAMESPACE::string &user, + const OCCI_STD_NAMESPACE::string &oldPassword, + const OCCI_STD_NAMESPACE::string &newPassword) + =0; + virtual void flushCache() =0; + + virtual OCIServer* getOCIServer() const =0; + virtual OCISvcCtx* getOCIServiceContext() const =0; + virtual OCISession* getOCISession() const =0; + + //new interfaces + + virtual Statement* createStatement(const UString &sql) = 0; + virtual MetaData getMetaData(const UString &object, + MetaData::ParamType prmtyp + = MetaData::PTYPE_UNK) const + =0; + virtual UString getClientCharSetUString() const + =0; + virtual UString getClientNCHARCharSetUString() const + =0; + virtual void changePassword(const UString &user, + const UString &oldPassword, + const UString &newPassword) + =0; + virtual OCCI_STD_NAMESPACE::string getTag() const =0; + virtual void setStmtCacheSize(unsigned int cacheSize) = 0; + virtual unsigned int getStmtCacheSize() const =0; + virtual Statement* createStatement(const OCCI_STD_NAMESPACE::string &sql, + const OCCI_STD_NAMESPACE::string &tag) = 0; + virtual void terminateStatement(Statement* stmt, + const OCCI_STD_NAMESPACE::string &tag) = 0; + virtual bool isCached(const OCCI_STD_NAMESPACE::string &sql, + const OCCI_STD_NAMESPACE::string &tag = "") = 0; + virtual void registerSubscriptions( + const OCCI_STD_NAMESPACE::vector& sub) =0; + virtual void unregisterSubscription(const aq::Subscription& sub) =0; + virtual void postToSubscriptions( + const OCCI_STD_NAMESPACE::vector& sub) =0; + virtual Statement* createStatement(const UString &sql, + const UString &tag) = 0; + virtual void terminateStatement(Statement* stmt, + const UString &tag) = 0; + virtual bool isCached(const UString &sql, + const UString &tag) = 0; + virtual void setTAFNotify( + int (*notifyFn)(Environment *env, Connection *conn, void *ctx, + FailOverType foType, FailOverEventType foEvent), + void *ctx) = 0; + virtual OCCI_STD_NAMESPACE::string getServerVersion() const =0; + virtual UString getServerVersionUString() const =0; + virtual void cancel() =0; +}; + +class StatelessConnectionPool +{ + public : + + enum PoolType + { + HETEROGENEOUS = OCI_DEFAULT, + HOMOGENEOUS = OCI_SPC_HOMOGENEOUS, + NO_RLB = OCI_SPC_NO_RLB, + USES_EXT_AUTH = 16 + }; + + enum BusyOption + { + WAIT = OCI_SPOOL_ATTRVAL_WAIT, + NOWAIT = OCI_SPOOL_ATTRVAL_NOWAIT, + FORCEGET = OCI_SPOOL_ATTRVAL_FORCEGET + }; + + enum DestroyMode + { + DEFAULT = OCI_DEFAULT, + SPD_FORCE = OCI_SPD_FORCE + }; + + virtual ~StatelessConnectionPool() {} + virtual unsigned int getBusyConnections() const =0; + virtual unsigned int getOpenConnections() const =0; + virtual unsigned int getMinConnections() const =0; + virtual unsigned int getMaxConnections() const =0; + virtual unsigned int getIncrConnections() const =0; + virtual OCCI_STD_NAMESPACE::string getPoolName() const =0; + virtual unsigned int getTimeOut() const =0; + virtual void setBusyOption(BusyOption busyOption) =0; + virtual BusyOption getBusyOption() const =0; + virtual void setTimeOut(unsigned int connTimeOut =0) =0; + virtual void setPoolSize(unsigned int maxConn =1, + unsigned int minConn =0, unsigned int incrConn =1) =0; + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &tag ="") =0; + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &Password, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) =0; + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &tag = "" , + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) =0; + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) =0; + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &tag="", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT ) =0; + virtual void releaseConnection (Connection *connection, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual void terminateConnection (Connection *connection) =0; + virtual void setStmtCacheSize(unsigned int cacheSize) =0; + virtual unsigned int getStmtCacheSize() const =0; + + virtual Connection* getConnection(const UString &tag)=0; + virtual Connection* getConnection(const UString &userName, + const UString &password, + const UString &tag)=0; + virtual Connection* getAnyTaggedConnection(const UString &tag)=0; + virtual Connection* getAnyTaggedConnection( const UString &userName, + const UString &Password, const UString &tag)=0 ; + virtual Connection* getProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &tag, + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT)=0; + virtual Connection* getProxyConnection(const UString &name, + const UString &tag, Connection::ProxyType + proxyType = Connection::PROXY_DEFAULT)=0; + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &tag, + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT)=0; + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + const UString &tag, + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT )=0; + virtual void releaseConnection(Connection *connection, + const UString &tag)=0; + + + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &Password, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "")= 0; + + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + + virtual Connection* getConnection( + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) = 0; + + + + virtual Connection* getConnection(const UString &userName, + const UString &password, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) = 0; + + virtual Connection* getAnyTaggedConnection( + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) =0; + + + + virtual Connection* getAnyTaggedConnection( const UString &userName, + const UString &Password, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) =0; + + virtual Connection* getProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, Connection::ProxyType proxyType) =0; + + virtual Connection* getProxyConnection(const UString &name, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, Connection::ProxyType proxyType) = 0; + + + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, + Connection::ProxyType proxyType) = 0; + + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, + Connection::ProxyType proxyType ) =0; + +}; + + +class ConnectionPool +{ + public : + + virtual ~ConnectionPool() {} + virtual unsigned int getBusyConnections() const + =0; + virtual unsigned int getOpenConnections() const + =0; + virtual unsigned int getMinConnections() const + =0; + virtual unsigned int getMaxConnections() const + =0; + virtual unsigned int getIncrConnections() const + =0; + virtual OCCI_STD_NAMESPACE::string getPoolName() const + =0; + virtual unsigned int getTimeOut() const + =0; + virtual void setErrorOnBusy() + =0; + virtual void setTimeOut(unsigned int connTimeOut =0) + =0; + virtual void setPoolSize(unsigned int minConn =0, + unsigned int maxConn =1, unsigned int incrConn =1) + =0; + virtual Connection* createConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password) =0; + + virtual Connection* createProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual Connection* createProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual void terminateConnection + (Connection *connection) =0; + + //new interfaces + + virtual Connection* createConnection( + const UString &userName, + const UString &password) =0; + + virtual Connection* createProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual Connection* createProxyConnection(const UString &name, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual void setStmtCacheSize(unsigned int cacheSize) =0; + virtual unsigned int getStmtCacheSize() const =0; + + virtual UString getPoolNameUString() const + =0; +}; + +class Environment +{ + public: + // class constants + + enum Mode + { + DEFAULT = OCI_DEFAULT, + OBJECT = OCI_OBJECT, + SHARED = OCI_SHARED, + NO_USERCALLBACKS = OCI_NO_UCB, + THREADED_MUTEXED = OCI_THREADED, + THREADED_UNMUTEXED = OCI_THREADED | OCI_NO_MUTEX, + EVENTS = OCI_EVENTS, + USE_LDAP = OCI_USE_LDAP + }; + + virtual ~Environment(){} + + // public methods + + static Environment * createEnvironment( + Mode mode = DEFAULT, + void *ctxp = 0, + void *(*malocfp)(void *ctxp, size_t size) = 0, + void *(*ralocfp)(void *ctxp, void *memptr, + size_t newsize) = 0, + void (*mfreefp)(void *ctxp, void *memptr) = 0); + + static Environment * createEnvironment( + const OCCI_STD_NAMESPACE::string &charset, + const OCCI_STD_NAMESPACE::string &ncharset, + Mode mode = DEFAULT, + void *ctxp = 0, + void *(*malocfp)(void *ctxp, size_t size) = 0, + void *(*ralocfp)(void *ctxp, void *memptr, + size_t newsize) = 0, + void (*mfreefp)(void *ctxp, void *memptr) = 0); + + static void terminateEnvironment(Environment *env); + + static Environment* getXAEnvironment(const + OCCI_STD_NAMESPACE::string& dbname); + + static void releaseXAEnvironment(Environment *env); + + static void getClientVersion( int &majorVersion, int &minorVersion, + int &updateNum, int &patchNum, + int &portUpdateNum ); + + + virtual Connection * createConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &connectString = "") = 0; + + virtual void terminateConnection(Connection *connection) = 0; + + virtual ConnectionPool* createConnectionPool( + const OCCI_STD_NAMESPACE::string &poolUserName, + const OCCI_STD_NAMESPACE::string &poolPassword, + const OCCI_STD_NAMESPACE::string &connectString ="", + unsigned int minConn =0, + unsigned int maxConn =1, unsigned int incrConn =1) = 0; + + virtual void terminateConnectionPool(ConnectionPool *poolp) = 0; + + virtual unsigned int getCurrentHeapSize() const = 0; + + virtual OCIEnv * getOCIEnvironment() const = 0; + + virtual Map *getMap() const = 0; + + virtual void setCacheMaxSize(unsigned int maxSize) = 0; + + virtual unsigned int getCacheMaxSize() const = 0; + + virtual void setCacheOptSize(unsigned int OptSize) = 0; + + virtual unsigned int getCacheOptSize() const = 0; + + + //new interfaces + + virtual Connection * createConnection(const UString &userName, + const UString &password, const UString &connectString) = 0; + + virtual ConnectionPool* createConnectionPool( + const UString &poolUserName, + const UString &poolPassword, const UString &connectString, + unsigned int minConn =0, + unsigned int maxConn =1, unsigned int incrConn =1) = 0; + + virtual Connection* getXAConnection(const + OCCI_STD_NAMESPACE::string& dbname) = 0; + + virtual void releaseXAConnection(Connection* conn) =0; + + virtual StatelessConnectionPool* createStatelessConnectionPool( + const OCCI_STD_NAMESPACE::string &poolUserName, + const OCCI_STD_NAMESPACE::string &poolPassword, + const OCCI_STD_NAMESPACE::string &connectString = "", + unsigned int maxConn = 1, unsigned int minConn = 0, + unsigned int incrConn = 1, + StatelessConnectionPool::PoolType pType + = StatelessConnectionPool::HETEROGENEOUS) = 0; + + virtual StatelessConnectionPool* createStatelessConnectionPool( + const UString &poolUserName, + const UString &poolPassword, + const UString &connectString, + unsigned int maxConn = 1, unsigned int minConn = 0, + unsigned int incrConn = 1, + StatelessConnectionPool::PoolType pType + = StatelessConnectionPool::HETEROGENEOUS) = 0; + + virtual void terminateStatelessConnectionPool(StatelessConnectionPool *poolp, + StatelessConnectionPool::DestroyMode mode = StatelessConnectionPool::DEFAULT) + = 0; + virtual void setLDAPAuthentication(unsigned int mode) =0; + + virtual unsigned int getLDAPAuthentication() const =0; + + virtual void setLDAPLoginNameAndPassword( + const OCCI_STD_NAMESPACE::string &login, + const OCCI_STD_NAMESPACE::string &passwd) =0; + + virtual void setLDAPAdminContext(const OCCI_STD_NAMESPACE::string &ctx)=0; + + virtual OCCI_STD_NAMESPACE::string getLDAPAdminContext() const =0; + + virtual void setLDAPHostAndPort(const OCCI_STD_NAMESPACE::string &host, + unsigned int port) =0; + + virtual OCCI_STD_NAMESPACE::string getLDAPHost() const =0; + + virtual unsigned int getLDAPPort() const =0; + + virtual void registerSubscriptions( + const OCCI_STD_NAMESPACE::vector& sub) =0; + + virtual void unregisterSubscription(const aq::Subscription& sub) =0; + + virtual void enableSubscription(const aq::Subscription& sub) =0; + + virtual void disableSubscription(const aq::Subscription& sub) =0; + + virtual bool getCacheSortedFlush() const = 0; + + virtual void setCacheSortedFlush(bool flag) = 0; + + virtual Connection * createConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &connectString, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity) = 0; + + virtual Connection * createConnection(const UString &userName, + const UString &password, const UString &connectString, + const UString &connectionclass, + const Connection::Purity purity) =0; + + private: + +}; + + + +class Map +{ + public: + + virtual ~Map(){} + virtual void put(const OCCI_STD_NAMESPACE::string&, void *(*)(void *), + void (*)(void *, void *)) = 0; + virtual void getReadSQL( + void *, unsigned int, void *, unsigned int, void **) const = 0; + virtual void getWriteSQL( + void *, unsigned int, void *, unsigned int, void **) const = 0; + virtual void put(const OCCI_STD_NAMESPACE::string&, + const OCCI_STD_NAMESPACE::string&, void *(*)(void *), + void (*)(void *, void *)) = 0; + virtual void putUTF16(const OCCI_STD_NAMESPACE::string&, + const OCCI_STD_NAMESPACE::string&, void *(*)(void *), + void (*)(void *, void *)) = 0; + + private: +}; + + + +class SQLException : public OCCI_STD_NAMESPACE::exception +{ + public: + + virtual int getErrorCode() const; + + virtual OCCI_STD_NAMESPACE::string getMessage() const; + + const char *what() const throw(); + + virtual void setErrorCtx(void *ctx); + + SQLException(); + + SQLException(const SQLException &e); + + void operator=(const SQLException &other); + + virtual ~SQLException() throw(); + + virtual int getXAErrorCode(const OCCI_STD_NAMESPACE::string& dbname) const; + + virtual UString getUStringMessage() const; + + virtual OCCI_STD_NAMESPACE::string getNLSMessage(Environment *env) const; + + virtual UString getNLSUStringMessage(Environment *env) const; + + protected: + + Ptr ptr_; + SQLException(SQLExceptionImpl *ptr); + + friend SQLException SQLExceptionCreate(int errorCode); + friend SQLException SQLExceptionCreate(void *handle, + int handleType); + friend class BatchSQLException; +}; + +class BatchSQLException : public SQLException +{ + public: + virtual ~BatchSQLException() throw(); + + unsigned int getFailedRowCount() const; + unsigned int getRowNum( unsigned int index ) const; + SQLException getException ( unsigned int index ) const; + + private: + BatchSQLException(); + + BatchSQLException(SQLExceptionImpl *ptr); + friend BatchSQLException BatchSQLExceptionCreate(void *handle); +}; + +class Statement +{ + public: + // class constants + + virtual ~Statement() {} + + enum Status + { + UNPREPARED, + PREPARED, + RESULT_SET_AVAILABLE, + UPDATE_COUNT_AVAILABLE, + NEEDS_STREAM_DATA, + STREAM_DATA_AVAILABLE + }; + + // common methods + + virtual void setSQL(const OCCI_STD_NAMESPACE::string &sql) = 0; + + virtual OCCI_STD_NAMESPACE::string getSQL() const = 0; + + virtual Status execute(const OCCI_STD_NAMESPACE::string &sql = "") = 0; + + virtual ResultSet * getResultSet() = 0; + + virtual unsigned int getUpdateCount() const = 0; + + virtual ResultSet * executeQuery( + const OCCI_STD_NAMESPACE::string &sql = "") = 0; + + virtual unsigned int executeUpdate( + const OCCI_STD_NAMESPACE::string &sql = "") = 0; + + virtual Status status() const = 0; + + virtual void closeResultSet(ResultSet *resultSet) = 0; + + virtual void setPrefetchRowCount(unsigned int rowCount) = 0; + + virtual void setPrefetchMemorySize(unsigned int bytes) = 0; + + virtual void setAutoCommit(bool autoCommit) = 0; + + virtual bool getAutoCommit() const = 0; + + virtual OCIStmt * getOCIStatement() const = 0; + + + // methods for prepared statements with IN + // parameters + + virtual void setMaxParamSize(unsigned int paramIndex,unsigned int maxSize)=0; + + virtual unsigned int getMaxParamSize(unsigned int paramIndex) const = 0; + + virtual void setNull(unsigned int paramIndex, Type type) = 0; + + virtual void setInt(unsigned int paramIndex, int x) = 0; + + virtual void setUInt(unsigned int paramIndex, unsigned int x) = 0; + + virtual void setFloat(unsigned int paramIndex, float x) = 0; + + virtual void setDouble(unsigned int paramIndex, double x) = 0; + + virtual void setNumber(unsigned int paramIndex, const Number &x) = 0; + + virtual void setString(unsigned int paramIndex, + const OCCI_STD_NAMESPACE::string &x) = 0; + + virtual void setBytes(unsigned int paramIndex, const Bytes &x) = 0; + + virtual void setDate(unsigned int paramIndex, const Date &x) = 0; + + virtual void setTimestamp(unsigned int paramIndex, const Timestamp &x) = 0; + + virtual void setBlob(unsigned int paramIndex, const Blob &x) = 0; + + virtual void setClob(unsigned int paramIndex, const Clob &x) = 0; + + virtual void setBfile(unsigned int paramIndex, const Bfile &x) = 0; + + virtual void setIntervalYM(unsigned int paramIndex, const IntervalYM &x) = 0; + + virtual void setIntervalDS(unsigned int paramIndex, const IntervalDS &x) = 0; + + virtual void setRowid(unsigned int paramIndex, const Bytes &x) = 0; + + virtual void setRef(unsigned int paramIndex, const RefAny &x) = 0; + + virtual void setObject(unsigned int paramIndex, PObject * x) = 0; + + virtual void setDataBuffer(unsigned int paramIndex, void *buffer, + Type type, + sb4 size, ub2 *length, sb2 *ind = NULL, + ub2 *rc = NULL) = 0; + + virtual void setDataBufferArray(unsigned int paramIndex, void *buffer, + Type type, + ub4 arraySize, ub4 *arrayLength, + sb4 elementSize, + ub2 *elementLength, sb2 *ind = NULL, + ub2 *rc = NULL) = 0; + + virtual void setCharSet(unsigned int paramIndex, + const OCCI_STD_NAMESPACE::string & charSet) = 0; + + virtual OCCI_STD_NAMESPACE::string getCharSet(unsigned int paramIndex) + const = 0; + + virtual void setDatabaseNCHARParam( + unsigned int paramIndex, bool isNCHAR) = 0; + + virtual bool getDatabaseNCHARParam(unsigned int paramIndex) const = 0; + + virtual void closeStream(Stream *stream) =0; + + virtual Stream * getStream(unsigned int paramIndex) = 0; + + virtual unsigned int getCurrentStreamParam() const = 0; + + virtual unsigned int getCurrentStreamIteration() const = 0; + + virtual void setBinaryStreamMode(unsigned int colIndex, + unsigned int size) =0; + + virtual void setCharacterStreamMode(unsigned int colIndex, + unsigned int size) =0; + + virtual void setMaxIterations(unsigned int maxIterations) = 0; + + virtual unsigned int getMaxIterations() const = 0; + + virtual void addIteration() = 0; + + virtual unsigned int getCurrentIteration() const = 0; + + virtual Status executeArrayUpdate(unsigned int arrayLength) = 0; + + + // methods for Callable Statements + + virtual void registerOutParam(unsigned int paramIndex, Type type, + unsigned int maxSize=0, const OCCI_STD_NAMESPACE::string &sqltype="") = 0; + + virtual bool isNull(unsigned int paramIndex) const = 0; + + virtual bool isTruncated(unsigned int paramIndex) const + =0; + + + virtual void setErrorOnNull(unsigned int paramIndex, + bool causeException) = 0; + + virtual void setErrorOnTruncate(unsigned int paramIndex, + bool causeException) = 0; + + virtual int preTruncationLength(unsigned int paramIndex) const + =0; + + + virtual int getInt(unsigned int paramIndex) = 0; + + virtual unsigned int getUInt(unsigned int paramIndex) = 0; + + virtual float getFloat(unsigned int paramIndex) = 0; + + virtual double getDouble(unsigned int paramIndex) = 0; + + virtual Number getNumber(unsigned int paramIndex) = 0; + + virtual OCCI_STD_NAMESPACE::string getString(unsigned int paramIndex) = 0; + + virtual Bytes getBytes(unsigned int paramIndex) = 0; + + virtual Date getDate(unsigned int paramIndex) = 0; + + virtual Timestamp getTimestamp(unsigned int paramIndex) = 0; + + virtual Bytes getRowid(unsigned int paramIndex) = 0; + + virtual PObject * getObject(unsigned int paramIndex) = 0; + + virtual Blob getBlob(unsigned int paramIndex) = 0; + + virtual Clob getClob(unsigned int paramIndex) = 0; + + virtual Bfile getBfile(unsigned int paramIndex) = 0; + + virtual IntervalYM getIntervalYM(unsigned int paramIndex) = 0; + + virtual IntervalDS getIntervalDS(unsigned int paramIndex) = 0; + + virtual RefAny getRef(unsigned int paramIndex) = 0; + + virtual ResultSet * getCursor(unsigned int paramIndex) = 0; + + virtual Connection* getConnection() const =0; + + //new interfaces + + virtual void setRef(unsigned int paramIndex, const RefAny &x, + const OCCI_STD_NAMESPACE::string &typName, + const OCCI_STD_NAMESPACE::string &schName = "") = 0; + + virtual void setSQLUString(const UString &sql) = 0; + + virtual UString getSQLUString() const = 0; + + virtual Status execute(const UString &sql) = 0; + + virtual ResultSet * executeQuery( + const UString &sql) = 0; + + virtual unsigned int executeUpdate( + const UString &sql) = 0; + + virtual void setBFloat(unsigned int paramIndex, const BFloat &fval) = 0; + + virtual void setBDouble(unsigned int paramIndex, const BDouble &dval) = 0; + + virtual void setUString(unsigned int paramIndex, + const UString &x) = 0; + + virtual void setCharSetUString(unsigned int paramIndex, + const UString & charSet) = 0; + + virtual UString getCharSetUString(unsigned int paramIndex) + const = 0; + + virtual void registerOutParam(unsigned int paramIndex, Type type, + unsigned int maxSize, const OCCI_STD_NAMESPACE::string &typName, + const OCCI_STD_NAMESPACE::string &schName) = 0; + + virtual void registerOutParam(unsigned int paramIndex, Type type, + unsigned int maxSize, const UString &typName, + const UString &schName) = 0; + + virtual BFloat getBFloat(unsigned int paramIndex) = 0; + + virtual BDouble getBDouble(unsigned int paramIndex) = 0; + + virtual UString getUString(unsigned int paramIndex) = 0; + + virtual void disableCaching() =0; + + virtual void setRef(unsigned int paramIndex, const RefAny &x, + const UString &typName, + const UString &schName) = 0; + + virtual void setBinaryStreamMode(unsigned int colIndex, + unsigned int size, bool INArg) =0; + + virtual void setCharacterStreamMode(unsigned int colIndex, + unsigned int size, bool INArg) =0; + + virtual void setNull(unsigned int paramIndex, Type type, + const OCCI_STD_NAMESPACE::string &typeName, + const OCCI_STD_NAMESPACE::string &schemaName = "") = 0; + + virtual void setNull(unsigned int paramIndex, Type type, + UString &typeName, UString &schemaName) = 0; + + virtual void setBatchErrorMode( bool batchErrorMode ) =0; + + virtual bool getBatchErrorMode( ) const =0; + +}; + + + +class ResultSet +{ + public: + // class constants + + enum Status + { + END_OF_FETCH = 0, + DATA_AVAILABLE, + STREAM_DATA_AVAILABLE + }; + virtual ~ResultSet(){} + + // public methods + + virtual Status next(unsigned int numRows = 1) = 0; + + virtual Status status() const = 0; + + virtual unsigned int getNumArrayRows() const = 0; + + virtual void cancel() = 0; + + virtual void setMaxColumnSize(unsigned int colIndex, unsigned int max) = 0; + + virtual unsigned int getMaxColumnSize(unsigned int colIndex) const = 0; + + virtual bool isNull(unsigned int colIndex) const = 0; + + virtual bool isTruncated(unsigned int paramIndex) const + =0; + + virtual void setErrorOnNull(unsigned int colIndex, bool causeException) = 0; + virtual void setErrorOnTruncate(unsigned int paramIndex, + bool causeException) =0; + + virtual int preTruncationLength(unsigned int paramIndex) const + =0; + + virtual int getInt(unsigned int colIndex) = 0; + + virtual unsigned int getUInt(unsigned int colIndex) = 0; + + virtual float getFloat(unsigned int colIndex) = 0; + + virtual double getDouble(unsigned int colIndex) = 0; + + virtual Number getNumber(unsigned int colIndex) = 0; + + virtual OCCI_STD_NAMESPACE::string getString(unsigned int colIndex) = 0; + + virtual Bytes getBytes(unsigned int colIndex) = 0; + + virtual Date getDate(unsigned int colIndex) = 0; + + virtual Timestamp getTimestamp(unsigned int colIndex) = 0; + + virtual Bytes getRowid(unsigned int colIndex) = 0; + + virtual PObject * getObject(unsigned int colIndex) = 0; + + virtual Blob getBlob(unsigned int colIndex) = 0; + + virtual Clob getClob(unsigned int colIndex) =0; + + virtual Bfile getBfile(unsigned int colIndex) = 0; + + virtual IntervalYM getIntervalYM(unsigned int colIndex) =0; + + virtual IntervalDS getIntervalDS(unsigned int colIndex) =0; + + virtual RefAny getRef(unsigned int colIndex) = 0; + + virtual Bytes getRowPosition() const = 0; + + virtual ResultSet * getCursor(unsigned int colIndex) = 0; + + virtual void setDataBuffer(unsigned int colIndex, void *buffer, Type type, + sb4 size = 0, ub2 *length = NULL, + sb2 *ind = NULL, ub2 *rc = NULL) = 0; + + virtual void setCharSet(unsigned int colIndex, + const OCCI_STD_NAMESPACE::string & charSet) = 0; + + virtual OCCI_STD_NAMESPACE::string getCharSet(unsigned int colIndex) + const = 0; + + virtual void setBinaryStreamMode(unsigned int colIndex, unsigned int size) + = 0; + + virtual void setCharacterStreamMode(unsigned int colIndex, unsigned int size) + = 0; + + virtual void setDatabaseNCHARParam(unsigned int paramIndex, + bool isNCHAR) = 0; + + virtual bool getDatabaseNCHARParam(unsigned int paramIndex) const = 0; + + virtual Stream * getStream(unsigned int colIndex) = 0; + + virtual void closeStream(Stream *stream) =0; + + virtual unsigned int getCurrentStreamColumn() const= 0; + + virtual unsigned int getCurrentStreamRow() const= 0; + + virtual OCCI_STD_NAMESPACE::vector getColumnListMetaData() const + = 0; + + virtual Statement* getStatement() const=0; + + //new interfaces + + virtual BFloat getBFloat(unsigned int colIndex) = 0; + + virtual BDouble getBDouble(unsigned int colIndex) = 0; + + virtual UString getUString(unsigned int colIndex) = 0; + + virtual void setCharSetUString(unsigned int colIndex, + const UString & charSet) = 0; + + virtual UString getCharSetUString(unsigned int colIndex) + const = 0; + + virtual void setPrefetchRowCount(unsigned int rowCount) = 0; + + virtual void setPrefetchMemorySize(unsigned int bytes) = 0; +}; + + +class Stream +{ + public : + + enum Status {READY_FOR_READ, READY_FOR_WRITE, INACTIVE}; + + virtual ~Stream(){} + virtual int readBuffer(char *buffer, unsigned int size) + =0; + virtual int readLastBuffer(char *buffer, unsigned int size) + =0; + virtual void writeBuffer(char *buffer, unsigned int size) + =0; + virtual void writeLastBuffer(char *buffer, unsigned int size) + =0; + virtual Status status() const =0; + +}; + +/*--------------------------------------------------------------------------- + PROTOTYPES USED BY FUNCTION TEMPLATES + -------------------------------------------------------------------------*/ + void getVectorOfPObjects( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVectorOfOCIRefs(ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVectorOfPObjects( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVectorOfOCIRefs(Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void setVectorOfPObjects( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVectorOfPObjects( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVectorOfPObjects( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVectorOfOCIRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector &vecind, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVectorOfOCIRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector &vecind, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVectorOfOCIRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector &vecind, + const UString &schemaName, + const UString &typeName) ; + void pinVectorOfOCIRefs(const Connection *conn, + OCCI_STD_NAMESPACE::vector & vecRef, + OCCI_STD_NAMESPACE::vector & vecCor, + OCCI_STD_NAMESPACE::vector &vecPObj,LockOptions &lockOpt ); + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------------ getVector for objects ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of objects + + PARAMETERS + rs - ResultSet + vect- reference to vector of objects(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of RefAny. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with objects. + + RETURNS + nothing + + NOTES + compatible SQL types : NTY + + will call getVector(..., vector) +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + +template +void getVector( ResultSet *rs, unsigned int index,OCCI_STD_NAMESPACE::vector +& vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(rs, index, vec_pobj); + + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for ( unsigned int i=0; i< size; i++) + vect.push_back((T)vec_pobj[i]); +} + +#else +template +void getVector( ResultSet *rs, unsigned int index, OCCI_STD_NAMESPACE::vector &vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(rs, index, vec_pobj); + + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + vect.push_back((T *)vec_pobj[i]); +} +#endif + +/*------------------------ getVector for objects ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of objects + + PARAMETERS + stmt - Statement + vect- reference to vector of objects(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of RefAny. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with objects. + + RETURNS + nothing + + NOTES + compatible SQL types : NTY + + will call getVector(..., vector) +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + +template +void getVector( Statement *stmt, unsigned int index, +OCCI_STD_NAMESPACE::vector &vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(stmt, index, vec_pobj); + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + vect.push_back((T)vec_pobj[i]); +} +#else +template +void getVector( Statement *stmt, unsigned int index, +OCCI_STD_NAMESPACE::vector &vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(stmt, index, vec_pobj); + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + vect.push_back((T *)vec_pobj[i]); +} +#endif + +/*------------------------ getVector for Ref ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of Ref + + PARAMETERS + rs - ResultSet + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) +template +void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(rs, index, vec_ref); + + const Connection *sess = rs->getStatement()->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } +} +#endif + +/*------------------------ setVector for PObject*---------------------------*/ +/* + NAME + SetVector - overloaded function. Binds the attribute in the current + position with a vector of objects. + + PARAMETERS + rs - ResultSet + vect- reference to vector of objects(OUT parameter). + + DESCRIPTION + Binds the column in the specified position with a vector of signed int . + The column at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with objects . + + RETURNS + nothing + + NOTES + compatible SQL types : SQLT_NTY + + This will be calling setVector(..., vector,..) + +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, sqltype); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const UString &schemaName, +const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} +#else +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, sqltype); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const UString &schemaName, +const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} +#endif + +/*------------------------ setVector for Ref---------------------------*/ +/* + NAME + setVector - overloaded function. Binds the attribute in the current + position with a vector of Ref. + + PARAMETERS + rs - ResultSet + vect- reference to vector of REF + + DESCRIPTION + Binds the column in the specified position with a vector of signed int . + The column at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with OCIRef* . + + RETURNS + nothing + + NOTES + compatible SQL types : REF + + This will just call setVector(..., vector,..) + + +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, sqltype); +} + +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} + +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector > &vect, + const UString &schemaName, + const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} +#endif + +/*------------------------ getVector for Ref ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of Ref + + PARAMETERS + stmt - Statement + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) +template +void getVector( Statement *stmt, unsigned int index, + OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(stmt, index, vec_ref); + + const Connection *sess = stmt->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref ()); // pushing a default-constructed Ref + else + vect.push_back(Ref (sess, (OCIRef *)vec_ref[i], FALSE)); + } + +} +#endif + +// Platform independent get/setVectorOfRefs method added +// get(set)Vector of Ref and get(set)VectorOfRefs are identical +// in functionality. + +/*------------------------ getVectorOfRefs for Ref ----------------------*/ +/* + NAME + getVectorOfRefs - overloaded function. Retrieves the attribute in the + current position as a vector of Ref + + PARAMETERS + rs - ResultSet + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ + +template +void getVectorOfRefs( ResultSet *rs, unsigned int index, +OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(rs, index, vec_ref); + + const Connection *sess = rs->getStatement()->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } +} + +/*------------------------ setVectorOfRefs for Ref-----------------------*/ +/* + NAME + setVectorOfRefs - overloaded function. Binds the attribute in the current + position with a vector of Ref. + + PARAMETERS + rs - ResultSet + vect- reference to vector of REF + + DESCRIPTION + Binds the column in the specified position with a vector of signed int . + The column at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with OCIRef* . + + RETURNS + nothing + + NOTES + compatible SQL types : REF + + This will just call setVector(..., vector,..) + + +*/ + +template +void setVectorOfRefs( Statement *stmt, unsigned int index, +const OCCI_STD_NAMESPACE::vector > &vect, +const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, sqltype); +} + +template +void setVectorOfRefs( Statement *stmt, unsigned int index, +const OCCI_STD_NAMESPACE::vector > &vect, +const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} + +template +void setVectorOfRefs( Statement *stmt, unsigned int index, +const OCCI_STD_NAMESPACE::vector > &vect, +const UString &schemaName, +const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} + +/*------------------------ getVectorOfRefs for Ref ----------------------*/ +/* + NAME + getVectorOfRefs - overloaded function. Retrieves the attribute in the + current position as a vector of Ref + + PARAMETERS + stmt - Statement + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ + +template +void getVectorOfRefs( Statement *stmt, unsigned int index, +OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(stmt, index, vec_ref); + + const Connection *sess = stmt->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref ()); // pushing a default-constructed Ref + else + vect.push_back(Ref (sess, (OCIRef *)vec_ref[i], FALSE)); + } +} +/*----------------------------- pinVectorOfRefs---------------------*/ +/* + NAME + pinVectorOfRefs - array pin implementation + + PARAMETERS + conn- Connection object + vecRef - vector of OCIRefs * + vecCor - vector of OCIComplexObject * + vecPOBj - vector of PObject * ( OUT ) + + DESCRIPTION + implements the array pin of refs passed and returns the corresponding + PObject s + + RETURNS + + NOTES +*/ +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +OCCI_STD_NAMESPACE::vector &vectObj, LockOptions lockOpt) +{ + + OCCI_STD_NAMESPACE::vector vecRef; + OCCI_STD_NAMESPACE::vector vecCor; + OCCI_STD_NAMESPACE::vector vecPObj; + unsigned int sz = vect.size(); + vecRef.reserve( sz ); + vecCor.reserve( sz ); + + for ( unsigned int i=0; i < sz; i++) + { + vecRef.push_back((void *)vect[i].getRef()); + vecCor.push_back((void *)vect[i].getCor()); + } + pinVectorOfOCIRefs(conn, vecRef, vecCor, vecPObj, lockOpt); + for ( unsigned int k=0; k < sz; k++) + { + vectObj.push_back((T *)vecPObj[k]); + vect[k].setPinnedObject(vecPObj[k]); + } +} + +/*----------------------------- pinVectorOfRefs---------------------*/ +/* + NAME + pinVectorOfRefs - array pin implementation + + PARAMETERS + conn- Connection object + vecRef - vector of OCIRefs * + vecCor - vector of OCIComplexObject * + + DESCRIPTION + implements the array pin of refs passed + + RETURNS + + NOTES +*/ +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +LockOptions lockOpt) +{ + + OCCI_STD_NAMESPACE::vector vecRef; + OCCI_STD_NAMESPACE::vector vecCor; + OCCI_STD_NAMESPACE::vector vecPObj; + unsigned int sz = vect.size(); + vecRef.reserve( sz ); + vecCor.reserve( sz ); + + for ( unsigned int i=0; i < sz; i++) + { + vecRef.push_back((void *)vect[i].getRef()); + vecCor.push_back((void *)vect[i].getCor()); + } + pinVectorOfOCIRefs(conn, vecRef, vecCor,vecPObj, lockOpt); + for ( unsigned int k=0; k < sz; k++) + vect[k].setPinnedObject(vecPObj[k]); +} + + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +} /* end of namespace occi */ +} /* end of namespace oracle */ +#endif /* OCCICONTROL_ORACLE */ + +#endif /* _olint */ diff --git a/OCI/include/occiData.h b/OCI/include/occiData.h new file mode 100644 index 0000000..cd50673 --- /dev/null +++ b/OCI/include/occiData.h @@ -0,0 +1,1167 @@ +/* Copyright (c) 2000, 2008, Oracle. All rights reserved. */ + +/* + NAME + occiData.h - header file for OCCI data classes + + DESCRIPTION + Class definitions for Stream, Blob, Clob ,Bfile, + Number, Date, IntervalYM, IntervalDS, Time, + Timestamp + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + slynn 03/18/08 - Add get/setContentType. + slynn 09/14/06 - Remove string.clear() + slynn 07/28/06 - Migrate to new 11g LOB terminology + slynn 06/21/06 - Add LobRegion + slynn 05/25/06 - New NG Lob Functionality. + cparampa 09/06/04 - Date changes + shiyer 10/31/03 - Timestamp constructors issue + rvallam 10/07/03 - bug 3089939 - add private method in Date to compute + hour and min component in daysBetween to be passed + to set method of IntervalDS. + cparampa 08/21/03 - added toCopy to IntervalDS and IntervalYM + cparampa 07/14/03 - make SubscriptionImpl friend of Bytes class. + rvallam 02/12/03 - modified BFloat/BDouble interface - BFloat/BDouble + type is now a struct + cparampa 01/20/03 - made ProducerImpl friend of Bytes class + rvallam 11/19/02 - objects support for interval class + shiyer 11/15/02 - Add UTF16 support to IntervalYM & IntervalDS + cparampa 12/11/02 - removed references to class Payload + cparampa 10/12/02 - AQ additions + shiyer 10/12/02 - Added UTF16 version of get/set CharsetId in Clob + shiyer 09/06/02 - OCCI globalization support + aahluwal 06/04/02 - bug 2360115 + vvinay 02/21/02 - operator= added for Bytes + gayyappa 10/23/01 - fix bug 2073327 , use string instead of + enum CharSet + vvinay 12/21/01 - signed char constructor and cast operator + (bug 2073334) + binary operator methods not friends any more + gayyappa 15/10/01 - add parameter toCopy to Lob/Timestamp private + constructors + rvallam 04/09/01 - change private constructor in Number to pass + parameter by reference and made it const + chliang 03/05/01 - disable olint + rvallam 01/27/02 - remove #include + gayyappa 01/17/01 - add methods/operators to Interval and + timestamp classes.. + gayyappa 12/15/00 - interface changes in set methods + rvallam 11/29/00 - change method signature in Bytes + added 3 new methods in Number + rvallam 10/20/00 - change method signatures in Date + rvallam 09/15/00 - make StmtImpl/ResultSetImpl friend to + interval classes + gayyappa 08/21/00 - modified timestamp, interval headers. + add OCIEnv to constructor of Bytes., + removed getOCIRaw from Bytes. + add const to setVector mthds of anydata. + add void* data member to Timestamp/Interval. + rvallam 08/10/00 - modified CORE class headers to add friends , + added private constructor in Bytes + slari 08/02/00 - comment out Stream + rratnam 08/04/00 - updated the LOB stream interface + rkasamse 08/07/00 - make getVector friend of Time + slari 07/31/00 - add const to Bytes methods + slari 07/25/00 - disable Bytes(Bytes *) + slari 07/23/00 - add Bytes + gayyappa 07/26/00 - update Timestamp, IntervalYM, IntervalDS. + gayyappa 07/04/00 - for fixing a problem in occiNumber + rratnam 06/13/00 - Updated LOB class headers + kmohan 05/31/00 - Change Environment to Environment * in + Date constructor + kmohan 05/29/00 - No string + rkasamse 04/25/00 - Added string class header + etucker 04/19/00 - Added CORE class headers + kmohan 04/11/00 - Creation + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCIDATA_ORACLE +# define OCCIDATA_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +#ifndef OCCICONTROL_ORACLE +#include +#endif + +namespace oracle { +namespace occi { +class Bytes +{ + + public: + + Bytes(const Environment *env = NULL); // default constructor + + Bytes(unsigned char *value, unsigned int count, + unsigned int offset = 0, const Environment *env = NULL); + + Bytes(const Bytes &e); // copy constructor + + + // public methods + + void getBytes(unsigned char *dst, unsigned int count, + unsigned int srcBegin = 0, + unsigned int dstBegin = 0) const; + + unsigned int length() const; + + unsigned char byteAt(unsigned int index) const; + + bool isNull() const; + + void setNull(); + + void operator=(const Bytes &other); + + ~Bytes(); + +private: + // private data members + Bytes(OCIEnv *,OCIRaw *) ; + Bytes(Ptr bytesPtr) ; + Ptr ptr_; + friend class AnyDataImpl; + friend class aq::MessageImpl; + friend class aq::ProducerImpl; + friend class aq::SubscriptionImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + +}; + +class Bfile +{ + public : + + Bfile(); + Bfile(const Connection *connectionp) ; + Bfile(const Bfile &srcBfile) ; + ~Bfile(); + unsigned int length() const ; + OCCI_STD_NAMESPACE::string getDirAlias() const ; + UString getUStringDirAlias() const ; + OCCI_STD_NAMESPACE::string getFileName() const ; + UString getUStringFileName() const ; + void setName(const OCCI_STD_NAMESPACE::string &dirAlias, + const OCCI_STD_NAMESPACE::string &fileName) ; + void setName(const UString &dirAlias, const UString &fileName) ; + bool fileExists() const ; + Bfile& operator =(const Bfile &srcBfile) ; + bool operator ==(const Bfile &srcBfile) const ; + bool operator !=(const Bfile &srcBfile) const ; + void setNull() ; + bool isNull() const ; + bool isInitialized() const; + void open() ; + void close() ; + bool isOpen() const ; + unsigned int read(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) const ; + Stream* getStream(unsigned int offset = 1, + unsigned int amount =0) ; + void closeStream(Stream *stream); + + private: + + //Data Members: + + // pointer to the FILE locator + OCIBFileLocator *filep; + + // pointer to the ConnectionImpl instance + const ConnectionImpl *connp; + + // pointer to the LobStreamImpl instance obtained from this FILE + LobStreamImpl *streamp; + + void *bfileExt; + + //Enumerations: + enum {MAXDIRNAMELEN = 32, MAXFILENAMELEN = 256}; + + //Constructor: + Bfile(const Connection *connectionp, + OCIBFileLocator *locatorp, bool toCopy = true) ; + + //Methods: + OCIBFileLocator* getLocator() const; + void do_getDirAlias( void * dirAlias, ub2 * dirAliasLen) const ; + void do_getFileName( void * fileName, ub2 * fileNameLen) const ; + void do_setName( void * alias, ub2 aliasLen, + void *fileName, ub2 fileNameLen); + // Friends + friend class AnyDataImpl; + friend class StatementImpl; + friend class ResultSetImpl; + friend class Blob; + friend class Clob; + friend class aq::MessageImpl; + + friend void getVector(const AnyData&, OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(Statement*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(ResultSet*, unsigned int , + OCCI_STD_NAMESPACE::vector&) ; + friend void setVector(AnyData&, const OCCI_STD_NAMESPACE::vector&) ; + friend void do_setVectorOfBfile(Statement*, unsigned int, + const OCCI_STD_NAMESPACE::vector&, void *, unsigned int, + void *, unsigned int ) ; + +#ifdef ORAXB8_DEFINED + friend void readVectorOfBfiles(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); +#endif +}; + + +#ifdef ORAXB8_DEFINED +// See the end of this file for implementation of LobRegion +template < typename lobType > class LobRegion +{ + private: + lobType *_primary; + oraub8 _primaryOffset; + oraub8 _offset; + oraub8 _length; + OCCI_STD_NAMESPACE::string _mimeType; + + void setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator); + + public: + LobRegion(); + ~LobRegion(); + lobType *getPrimary(); + oraub8 getPrimaryOffset(); + oraub8 getOffset(); + oraub8 getLength(); + OCCI_STD_NAMESPACE::string getMimeType(); + + friend class Blob; + friend class Clob; +}; + +typedef LobRegion BlobRegion; +typedef LobRegion ClobRegion; +#endif + + +class Blob +{ + public: + + Blob(); + Blob(const Connection *connectionp) ; + Blob(const Blob &srcBlob) ; + ~Blob(); + unsigned int getChunkSize() const ; + unsigned int length() const ; + Blob& operator =(const Blob &srcBlob) ; + bool operator ==(const Blob &srcBlob) const ; + bool operator !=(const Blob &srcBlob) const ; + void setNull() ; + bool isNull() const ; + void setEmpty() ; + void setEmpty(const Connection *connectionp) ; + bool isInitialized() const; + void open(LobOpenMode mode=OCCI_LOB_READWRITE) ; + void close() ; + bool isOpen() const ; + void copy(const Blob &srcBlob, unsigned int numBytes, + unsigned int dstOffset =1, unsigned int srcOffset =1) ; + void copy(const Bfile &srcBfile, unsigned int numBytes, + unsigned int dstOffset =1, unsigned int srcOffset =1) ; + void append(const Blob &srcBlob) ; + unsigned int read(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) const ; + unsigned int write(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) ; + unsigned int writeChunk(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) ; + void trim(unsigned int newlen) ; + Stream* getStream(unsigned int offset = 1, + unsigned int amount =0) ; + void closeStream(Stream *stream); + LobOptionValue getOptions(LobOptionType optType); + void setOptions(LobOptionType optType, LobOptionValue value); + OCCI_STD_NAMESPACE::string getContentType(void); + void setContentType(const OCCI_STD_NAMESPACE::string contentType); + + void getDeduplicateRegions(OCCI_STD_NAMESPACE::vector ®ions); + private: + + //Data Members: + + // pointer to the BLOB locator + OCIBlobLocator *lobp; + + // pointer to the ConnectionImpl instance + const ConnectionImpl *connp; + + // pointer to the LobStreamImpl instance obtained from this LOB + LobStreamImpl *streamp; + + //for future use ! + void *blobExt; + + //Constructor: + Blob(const Connection *connectionp, + OCIBlobLocator *locatorp, bool toCopy=true) ; + + //Methods: + OCIBlobLocator* getLocator() const; + + // Friends + friend class AnyDataImpl; + friend class StatementImpl; + friend class ResultSetImpl; + +#ifdef ORAXB8_DEFINED + friend void + LobRegion::setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator); +#endif + friend void getVector(const AnyData&, OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(Statement*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(ResultSet*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void setVector(AnyData&, const OCCI_STD_NAMESPACE::vector&) ; + friend void do_setVectorOfBlob(Statement*, unsigned int, + const OCCI_STD_NAMESPACE::vector&, void *, + unsigned int, void *, unsigned int ) ; +#ifdef ORAXB8_DEFINED + friend void readVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + friend void writeVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); +#endif +}; + +class Clob +{ + public: + + Clob(); + Clob(const Connection *connectionp) ; + Clob(const Clob &srcClob) ; + ~Clob(); + unsigned int getChunkSize() const ; + unsigned int length() const ; + OCCI_STD_NAMESPACE::string getCharSetId() const; + CharSetForm getCharSetForm() const; + void setCharSetId( const OCCI_STD_NAMESPACE::string &charset) ; + void setCharSetForm( CharSetForm csfrm) ; + Clob& operator =(const Clob &srcClob) ; + bool operator ==(const Clob &srcClob) const ; + bool operator !=(const Clob &srcClob) const ; + void setNull() ; + bool isNull() const ; + void setEmpty() ; + void setEmpty(const Connection *connectionp) ; + bool isInitialized() const; + void open(LobOpenMode mode=OCCI_LOB_READWRITE) ; + void close() ; + bool isOpen() const ; + void copy(const Clob &srcClob, unsigned int numBytes, + unsigned int dstOffset = 1, unsigned int srcOffset = 1) ; + void copy(const Bfile &srcBfile, unsigned int numBytes, + unsigned int dstOffset = 1, unsigned int srcOffset = 1) ; + void append(const Clob &srcClob) ; + unsigned int read(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) const; + unsigned int read(unsigned int amt, utext *buffer, + unsigned int bufsize, unsigned int offset = 1) const; + unsigned int write(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + unsigned int write(unsigned int amt, utext *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + unsigned int writeChunk(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + unsigned int writeChunk(unsigned int amt, utext *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + void trim(unsigned int newlen) ; + Stream* getStream(unsigned int offset = 1, + unsigned int amount =0 ); + void closeStream(Stream *stream); + LobOptionValue getOptions(LobOptionType optType); + void setOptions(LobOptionType optType, LobOptionValue value); + OCCI_STD_NAMESPACE::string getContentType(void); + void setContentType(const OCCI_STD_NAMESPACE::string contentType); + + UString getCharSetIdUString() const; + void setCharSetIdUString( const UString &charset) ; + + void getDeduplicateRegions(OCCI_STD_NAMESPACE::vector ®ions); + + private: + + //Data Members: + + // pointer to the CLOB locator + OCIClobLocator *lobp; + + // pointer to the ConnectionImpl instance + const ConnectionImpl *connp; + + // pointer to the LobStreamImpl instance obtained from this LOB + LobStreamImpl *streamp; + + //charset id + ub2 charsetId; + + //charset form + CharSetForm charsetForm; + + //for future use ! + void *clobExt; + + //Constructor: + Clob(const Connection *connectionp, + OCIClobLocator *locatorp, bool toCopy =true ) ; + + //Methods: + OCIClobLocator* getLocator() const; + unsigned int do_read( unsigned int amt, void *buffer, + unsigned int bufsize, unsigned int offset) const; + unsigned int do_write( unsigned int amt, void *buffer, + unsigned int bufsize, unsigned int offset) ; + unsigned int do_writeChunk( unsigned int amt, void *buffer, + unsigned int bufsize, unsigned int offset) ; + + // Friends + friend class AnyDataImpl; + friend class StatementImpl; + friend class ResultSetImpl; + +#ifdef ORAXB8_DEFINED + friend void + LobRegion::setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator); +#endif + friend void getVector(const AnyData&, OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(Statement*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(ResultSet*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void setVector(AnyData&, const OCCI_STD_NAMESPACE::vector&) ; + friend void do_setVectorOfClob(Statement*, unsigned int, + const OCCI_STD_NAMESPACE::vector&, void *, + unsigned int, void *, unsigned int ) ; +#ifdef ORAXB8_DEFINED + friend void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + friend void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + friend void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); + friend void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); +#endif +}; + +class Number +{ + + public: + + // Constructors + /* default constructor added */ + Number(); + Number(const Number &srcNum); + Number(long double val) ; + Number(double val) ; + Number(float val) ; + Number(long val) ; + Number(int val) ; + Number(short val) ; + Number(char val) ; + Number(signed char val); + Number(unsigned long val) ; + Number(unsigned int val) ; + Number(unsigned short val) ; + Number(unsigned char val) ; + + ~Number(); + // Methods + const Number abs() const ; + // unary negate + const Number operator-() ; + // unary increment + Number& operator++() ; + const Number operator++(int) ; + // unary decrement + Number& operator--() ; + const Number operator--(int) ; + // assigment operator + Number& operator=(const Number &a); + // add and assign + Number& operator+=(const Number &a) ; + // subtract and assign + Number& operator-=(const Number &a) ; + // Mulitply an assign + Number& operator*=(const Number &a) ; + // divide and assign + Number& operator/=(const Number &a) ; + // Modulo and assign + Number& operator%=(const Number &a) ; + // casting operators + operator long() const; + operator int() const; + operator short() const; + operator char() const; + operator signed char() const; + operator unsigned long() const; + operator unsigned int() const; + operator unsigned short() const; + operator unsigned char() const; + operator long double() const; + operator double() const; + operator float() const; + // Decimal shift + const Number shift(int val) const ; + // Integer Power + const Number intPower(int val) const ; + const Number ceil() const ; + const Number floor() const ; + const Number squareroot() const ; + int sign() const ; + // conversion routines + // Format Number and return as a OCCI_STD_NAMESPACE::string + OCCI_STD_NAMESPACE::string toText(const Environment *envp, + const OCCI_STD_NAMESPACE::string &fmt, + const OCCI_STD_NAMESPACE::string &nlsParam="") const + ; + UString toText(const Environment *envp, + const UString &fmt,const UString &nlsParam) const + ; + // Create an Number from formatted text + void fromText(const Environment *envp, + const OCCI_STD_NAMESPACE::string &number, + const OCCI_STD_NAMESPACE::string &fmt, + const OCCI_STD_NAMESPACE::string &nlsParam = "") + ; + void fromText(const Environment *envp, + const UString &number, + const UString &fmt, const UString &nlsParam); + void fromBytes(const Bytes &s) ; + Bytes toBytes() const; + // truncate digits + const Number trunc(int decplace) const ; + // round to the decplace place. + const Number round(int decplace) const ; + // returns an Number with digits decimal digits + const Number prec(int digits) const ; + const Number sin() const ; + const Number cos() const ; + const Number tan() const ; + const Number hypSin() const ; + const Number hypCos() const ; + const Number hypTan() const ; + const Number arcSin() const ; + const Number arcCos() const ; + const Number arcTan() const ; + const Number arcTan2(const Number &val) const; + const Number power(const Number &val) const; + const Number exp() const ; + const Number ln() const ; + const Number log(const Number &val) const; + bool isNull() const; + void setNull(); + private: + /* Private constructor for constructing number from methods inside */ + Number(const OCINumber &result); + OCINumber getOCINumber() const; + + OCINumber data; + /* a flag to indicate if the Number is null */ + bool numberIsNull; + void *numberExt; + + // a >= b + friend bool operator>=(const Number &a, const Number &b); + // a < = b + friend bool operator<=(const Number &a, const Number &b); + // a > b + friend bool operator>(const Number &a, const Number &b); + // a < b + friend bool operator<(const Number &a, const Number &b); + + friend class IntervalDS; + friend class IntervalYM; + friend const IntervalYM operator*(const IntervalYM &a, + const Number& factor) ; + friend const IntervalDS operator*(const IntervalDS &a, + const Number& factor) ; + friend const IntervalYM operator/(const IntervalYM &a, + const Number &factor) ; + friend const IntervalDS operator/(const IntervalDS &a, + const Number &factor) ; + friend class ResultSetImpl; + friend class StatementImpl; + friend class AnyDataImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + friend Number MetaData::getNumber(MetaData::AttrId attrid) const ; + friend void getVector(Statement *stmt, unsigned int paramIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfNumber(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, void *schemaName, + unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen); + friend void getVector(ResultSet *rs, unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect); + +}; + +class Date +{ + public: + + // Constructors + Date(); + Date(const Date &a); + Date(const Environment *envp,int year = 1,unsigned int month = 1, + unsigned int day = 1,unsigned int hour = 0, + unsigned int minute = 0, unsigned int seconds = 0); + ~Date(); + // Methods + + void setDate(int year = 1,unsigned int month = 1,unsigned int day = 1, + unsigned int hour = 0,unsigned int minute = 0, + unsigned int seconds = 0); + void getDate(int &year,unsigned int &month,unsigned int &day, + unsigned int &hour ,unsigned int &min ,unsigned int &sec) const; + Bytes toBytes() const ; + void fromBytes(const Bytes &byteStream, + const Environment *envp = NULL); + OCCI_STD_NAMESPACE::string toText( + const OCCI_STD_NAMESPACE::string &fmt = "", + const OCCI_STD_NAMESPACE::string &nlsParam = "") const; + UString toText( + const UString &fmt , + const UString &nlsParam ) const; + void fromText(const OCCI_STD_NAMESPACE::string &datestr, + const OCCI_STD_NAMESPACE::string &fmt = "", + const OCCI_STD_NAMESPACE::string &nlsParam = "", + const Environment *envp = NULL); + void fromText(const UString &datestr, + const UString &fmt , const UString &nlsParam , + const Environment *envp = NULL); + Date toZone(const OCCI_STD_NAMESPACE::string &zone1, + const OCCI_STD_NAMESPACE::string &zone2) const; + Date& operator=(const Date &d); + Date addMonths(int i) const; + Date addDays(int i) const ; + Date lastDay() const ; + IntervalDS daysBetween(const Date &d) const; + Date nextDay(const OCCI_STD_NAMESPACE::string &dow) const; + Date nextDay(const UString &dow) const; + bool isNull() const; + void setNull(); + static Date getSystemDate(const Environment *envp) ; + + private: + OCIDate date; + const EnvironmentImpl *envp; + bool dateIsNull; + void *dateExt; + + /* private constructor */ + Date(const Environment *env,OCIDate dateval); + OCIDate getOCIDate() const; + void constructHourAndMinute(sb4 &seconds, sb4 &hours, sb4 &minutes) const; + friend bool operator==(const Date &a,const Date &b); + friend bool operator>(const Date &a,const Date &b); + friend bool operator<(const Date &a,const Date &b); + friend bool operator!=(const Date &a,const Date &b); + friend bool operator>=(const Date &a,const Date &b); + friend bool operator<=(const Date &a,const Date &b); + friend class ResultSetImpl; + friend class StatementImpl; + friend class AnyDataImpl; + friend class aq::MessageImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect); + friend void getVector(Statement *stmt, unsigned int paramIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfDate(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, void *schemaName, + unsigned int schemaNameLen,void *typeName, unsigned int typeNameLen) ; + friend void getVector(ResultSet *rs, unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + +}; //class Date + +class Timestamp +{ + public: + Timestamp() ; + + Timestamp( const Environment *env, int year=1, + unsigned int month=1, unsigned int day=1, unsigned int hour=0, + unsigned int min=0 ,unsigned int sec=0, unsigned int fs=0, + int tzhour=0, int tzmin=0) ; + Timestamp( const Environment *env, int year, + unsigned int month, unsigned int day, unsigned int hour, + unsigned int min ,unsigned int sec, unsigned int fs, + const OCCI_STD_NAMESPACE::string &timezone); + Timestamp( const Environment *env, int year, + unsigned int month, unsigned int day, unsigned int hour, + unsigned int min ,unsigned int sec, unsigned int fs, + const UString &timezone); + Timestamp( const Timestamp &src) ; + ~Timestamp(); + + void getTimeZoneOffset( int &hour, int &minute) const ; + void getTime( unsigned int &hour, unsigned int &minute, + unsigned int &second, unsigned int &fs) const ; + void getDate( int &year, unsigned int &month, unsigned int &day )const ; + OCCI_STD_NAMESPACE::string toText(const OCCI_STD_NAMESPACE::string &fmt, + unsigned int fsprec, + const OCCI_STD_NAMESPACE::string &nlsParam ="") const ; + UString toText(const UString &fmt, + unsigned int fsprec, const UString &nlsParam ) const ; + void setTimeZoneOffset( int hour, int minute) ; + void setTime( unsigned int hour, unsigned int minute, + unsigned int second, unsigned int fs) ; + void setDate( int year, unsigned int month, unsigned int day ) ; + void setNull() ; + void fromText( const OCCI_STD_NAMESPACE::string ×tmpStr, + const OCCI_STD_NAMESPACE::string &fmt , + const OCCI_STD_NAMESPACE::string &nlsParam= "", + const Environment *env =NULL); + void fromText( const UString ×tmpStr, + const UString &fmt , const UString &nlsParam, + const Environment *env =NULL); + bool isNull() const; + Timestamp & operator =( const Timestamp &src) ; + const IntervalYM subYM(const Timestamp& val) const ; + const IntervalDS subDS(const Timestamp& val) const ; + const Timestamp intervalAdd(const IntervalDS& val) const ; + const Timestamp intervalSub(const IntervalDS& val) const ; + const Timestamp intervalAdd(const IntervalYM& val) const ; + const Timestamp intervalSub(const IntervalYM& val) const ; + + friend bool operator==(const Timestamp &a,const Timestamp &b); + friend bool operator>(const Timestamp &a,const Timestamp &b); + friend bool operator<(const Timestamp &a,const Timestamp &b); + friend bool operator !=(const Timestamp &a,const Timestamp &b); + friend bool operator >=(const Timestamp &a,const Timestamp &b); + friend bool operator <=(const Timestamp &a,const Timestamp &b); + + friend class ResultSetImpl; + friend class StatementImpl; + friend class AnyDataImpl; + + private: + OCIDateTime *ocidatetime; + OCIEnv *ocienv; + void *timestampExt; + + OCIDateTime *getOCIDateTime() const; + Timestamp( OCIEnv *env, OCIDateTime *dt, bool toCopy = true) ; + void allocateDataMembers( OCIEnv *env) ; + void do_TimestampConstruct( const Environment *env, int year, + unsigned int month, unsigned int day, unsigned int hour, unsigned int min, + unsigned int sec, unsigned int fs, void *tzinter); + + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + friend Timestamp MetaData::getTimestamp( + MetaData::AttrId attrid) const ; + friend void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfTimestamp(Statement *stmt, + unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + void *schemaName, unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen) ; +}; // class Timestamp + +class IntervalDS +{ + + public: + IntervalDS() ; + IntervalDS( const Environment *env,int day=0, + int hour=0, int minute=0, int second=0, + int fs=0) ; + IntervalDS( const IntervalDS &src) ; + + ~IntervalDS(); + + int getDay () const ; + int getHour () const ; + int getMinute () const ; + int getSecond() const ; + int getFracSec () const ; + void set( int day, int hour, int minute, int second, int fracsec) ; + void setNull() ; + void fromText( const OCCI_STD_NAMESPACE::string &inpstr, + const OCCI_STD_NAMESPACE::string &nlsParam ="", + const Environment *env=NULL) ; + OCCI_STD_NAMESPACE::string toText( unsigned int lfprec, unsigned int fsprec, + const OCCI_STD_NAMESPACE::string &nlsParam="") const ; + bool isNull() const; + IntervalDS& operator =( const IntervalDS &src) ; + IntervalDS& operator +=( const IntervalDS &a); + IntervalDS& operator -=( const IntervalDS &a); + IntervalDS& operator *=( const Number &factor); + IntervalDS& operator /=( const Number &factor); + + friend bool operator>(const IntervalDS &a, + const IntervalDS &b) ; + friend bool operator<(const IntervalDS &a, + const IntervalDS &b) ; + friend bool operator >=( const IntervalDS &a, + const IntervalDS &b); + friend bool operator <=( const IntervalDS &a, + const IntervalDS &b); + + //UTF16 support + void fromUText( const UString &inpstr, const Environment *env=NULL ); + UString toUText( unsigned int lfprec, unsigned int fsprec) const; + + private: + OCIInterval *ociinter; + OCIEnv *ocienv; + void *intervalDSExt; + + IntervalDS( OCIEnv *env, OCIInterval *inter, bool toCopy = true) ; + OCIInterval * getOCIInterval() const; + + void allocateDataMembers( OCIEnv *env) ; + friend const IntervalDS Timestamp::subDS( + const Timestamp& val) const ; + friend const Timestamp Timestamp::intervalAdd( + const IntervalDS& val) const ; + friend const Timestamp Timestamp::intervalSub( + const IntervalDS& val) const ; + friend class Date; + friend void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfIntervalDS(Statement *stmt, + unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + void *schemaName, unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen) ; + friend class StatementImpl; + friend class ResultSetImpl; + friend class AnyDataImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + + +}; //class IntervalDS + +class IntervalYM +{ + + public: + IntervalYM() ; + IntervalYM( const Environment *env,int year=0, int month=0) ; + IntervalYM( const IntervalYM &src) ; + ~IntervalYM(); + + int getYear() const ; + int getMonth() const ; + + void set( int year, int month) ; + void setNull() ; + void fromText( const OCCI_STD_NAMESPACE::string &inpstr, + const OCCI_STD_NAMESPACE::string &nlsParam="", + const Environment *env=NULL) ; + OCCI_STD_NAMESPACE::string toText( unsigned int lfprec, + const OCCI_STD_NAMESPACE::string &nlsParam="") const; + bool isNull() const; + IntervalYM & operator =( const IntervalYM &src) ; + IntervalYM& operator +=( const IntervalYM &a); + IntervalYM& operator -=( const IntervalYM &a); + IntervalYM& operator *=( const Number &factor); + IntervalYM& operator /=( const Number &factor); + + friend bool operator>(const IntervalYM &a, const IntervalYM &b) ; + friend bool operator<( const IntervalYM &a, const IntervalYM &b) ; + friend bool operator >=(const IntervalYM &a, const IntervalYM &b); + friend bool operator <=(const IntervalYM &a, const IntervalYM &b); + + //UTF16 support + void fromUText( const UString &inpstr, const Environment *env=NULL ); + UString toUText( unsigned int lfprec ) const; + + private: + OCIInterval *ociinter; + OCIEnv *ocienv; + void *intervalYMExt; + + IntervalYM( OCIEnv *env, OCIInterval *inter, bool toCopy = true) ; + OCIInterval *getOCIInterval() const; + void allocateDataMembers( OCIEnv *env) ; + friend const IntervalYM Timestamp :: subYM( + const Timestamp& val) const ; + friend const Timestamp Timestamp::intervalAdd( + const IntervalYM &val) const ; + friend const Timestamp Timestamp::intervalSub( + const IntervalYM &val) const ; + + friend void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfIntervalYM(Statement *stmt, + unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + void *schemaName, unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen) ; + + friend class StatementImpl; + friend class ResultSetImpl; + friend class AnyDataImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + +}; //class IntervalYM + + +Number operator+(const Number &a, const Number &b) ; +Number operator/(const Number ÷nd, const Number &divisor) ; +Number operator*(const Number &a, const Number &b) ; +Number operator%(const Number &a, const Number &b) ; +Number operator-(const Number &subtrahend, const Number &subtractor) ; +bool operator==(const Number &a, const Number &b); +bool operator!=(const Number &a, const Number &b); + +const IntervalYM operator+(const IntervalYM &a, const IntervalYM &b) ; +const IntervalYM operator-(const IntervalYM &a, const IntervalYM &b) ; +const IntervalYM operator*(const IntervalYM &a, const Number& factor); +const IntervalYM operator/(const IntervalYM &a, const Number &factor); +bool operator==(const IntervalYM &a, const IntervalYM &b) ; +bool operator!=(const IntervalYM &a, const IntervalYM &b) ; + +const IntervalDS operator+(const IntervalDS &a, const IntervalDS &b) ; +const IntervalDS operator-(const IntervalDS &a, const IntervalDS &b) ; +const IntervalDS operator*(const IntervalDS &a, const Number& factor); +const IntervalDS operator/(const IntervalDS &a, const Number &factor); +bool operator==(const IntervalDS &a, const IntervalDS &b) ; +bool operator!=(const IntervalDS &a, const IntervalDS &b) ; + + +typedef struct BFloat +{ + float value; + bool isNull; + + BFloat() + { + isNull = false; + value = 0.; + } +} BFloat; + +typedef struct BDouble +{ + double value; + bool isNull; + + BDouble() + { + isNull = false; + value = 0.; + } +} BDouble; + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#ifdef ORAXB8_DEFINED +/* + NAME + Lob Region class + + DESCRIPTION + Contains the implementation of the Lob Region template Class. + This class is the underlying implementation for the BlobRegion and + ClobRegion classes. + + RELATED DOCUMENTS + Functional/Design Specifications: + 18209 - Next Generation LOBs: API + 18206 - Next Generation LOBs: Comb. Storage, Compressio & Encryption + + EXPORT FUNCTION(S) + LobRegion() - constructors + ~LobRegion() - destructor + getPrimary() - Get the Primary Lob object + getPrimaryOffset() - Get the offset of this region in the Primary Lob. + getOffset() - Get the offset of this region in this lob. + getLength() - Get the length of this region + getMimeType() - Get the mime type of this region + + PUBLIC IMPLEMENTATION FUNCTION(S) + + INTERNAL FUNCTION(S) + none + + EXAMPLES + + NOTES +*/ + +/*------------------------------ LobRegion ------------------*/ +/* + NAME + LobRegion - constructor for the class + + PARAMETERS + none + + DESCRIPTION + default constructor + + RETURNS + Nothing + + NOTES +*/ +template +LobRegion::LobRegion() +{ + _primary = (lobType *)0; + _primaryOffset = 0; + _offset = 0; + _length = 0; +} + +/*------------------------------ ~LobRegion ------------------*/ +/* + NAME + ~LobRegion - destructor for the class + + PARAMETERS + none + + DESCRIPTION + default constructor + + RETURNS + Nothing + + NOTES +*/ +template +LobRegion::~LobRegion() +{ + if (_primary != (lobType *)0) + { + delete _primary; + } +} + +template +lobType *LobRegion::getPrimary() +{ + return _primary; +} + +template +oraub8 LobRegion::getPrimaryOffset() +{ + return _primaryOffset; +} + +template +oraub8 LobRegion::getOffset() +{ + return _offset; +} + +template +oraub8 LobRegion::getLength() +{ + return _length; +} + +template +OCCI_STD_NAMESPACE::string LobRegion::getMimeType() +{ + return _mimeType; +} + +template +void LobRegion::setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator) +{ + if (locator != (OCILobLocator *)0) + { + _primary = new lobType(connp, locator, true); + } +} + +#endif /* ORAXB8_DEFINED */ + +} /* end of namespace occi */ +} /* end of namespace oracle */ +#endif /* OCCIDATA_ORACLE */ + +#endif /* _olint */ diff --git a/OCI/include/occiObjects.h b/OCI/include/occiObjects.h new file mode 100644 index 0000000..1b301ad --- /dev/null +++ b/OCI/include/occiObjects.h @@ -0,0 +1,910 @@ +/* Copyright (c) 2000, 2007, Oracle. All rights reserved. */ + +/* + NAME + occiObjects.h - header file for OCCI object classes + + DESCRIPTION + Class definitions for Ref, RefAny, AnyData + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCIOBJECTS_ORACLE +# define OCCIOBJECTS_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +namespace oracle { +namespace occi { +struct AnyDataCtx { + ConnectionImpl *occiSession; + OCIAnyData *anyData; + void *objHeader; + ub4 errNum; +}; +typedef struct AnyDataCtx AnyDataCtx; + +class PObject +{ + public: + enum LockOption {OCCI_LOCK_WAIT, OCCI_LOCK_NOWAIT}; + enum UnpinOption {OCCI_PINCOUNT_DECR, OCCI_PINCOUNT_RESET}; + static void destroy(void *); + static void refresh(void *); + PObject(); + PObject(const void *ctx); + PObject(const PObject& obj); + virtual ~PObject(); + PObject& operator=(const PObject& obj); + void *operator new(size_t size); + void *operator new(size_t size, const Connection *x, + const OCCI_STD_NAMESPACE::string& tablename, + const char *typeName); + void *operator new(size_t size, const Connection *sess, + const OCCI_STD_NAMESPACE::string& tablename, + const OCCI_STD_NAMESPACE::string& typName , + const OCCI_STD_NAMESPACE::string& schTabName="", + const OCCI_STD_NAMESPACE::string& schTypName = ""); + void *operator new(size_t size, const Connection *sess, + const UString& tablename, const UString &typName, + const UString& schTabName, const UString& schTypName); + void *operator new(size_t size, void *adctx); + void operator delete(void *obj, size_t size); + RefAny getRef() const; + bool isLocked() const; + void unpin(UnpinOption mode=OCCI_PINCOUNT_DECR); + void pin(); + void lock(PObject::LockOption lock_option); + void unmark(); + void flush(); + void markDelete(); + void markModified(); + bool isNull() const; + void setNull(); + const Connection *getConnection() const; + virtual OCCI_STD_NAMESPACE::string getSQLTypeName() const = 0; + virtual void getSQLTypeName(Environment *env, void **schName, + unsigned int &schNameLen, void **typeName, + unsigned int &typeNameLen) const = 0; + void getSQLTypeName(Environment *env, void *(*rSQL)(void *), + void **schname, unsigned int &schnamelen, + void **typname, unsigned int &typnamelen) const; + virtual void writeSQL(AnyData& stream) = 0; + virtual void readSQL(AnyData& stream) = 0; + private: + static void initialise( void * obj, const Connection * sess, + void *schTabName, unsigned int schTabLen, + void *tableName, unsigned int tabLen, + void *schTypName, unsigned int schTypLen, + void *typeName, unsigned int typLen); + + ConnectionImpl *occiSession_; + void *objHeader_; + ub2 customNewed_; + enum {CUSTOM_NEWED = 0x5cde}; + ub2 flags_; + enum {NULL_INFO = 0x0001, GARBAGE_COLLECTED = 0x0002, + REFRESH_OBJECT = 0x0004, + CACHED_OBJECT = 0xBAF8}; + //check PObject implementation for CACHED_OBJECT flag + // for future use + void *pobjectExt; + friend class RefImpl; +}; + +class AnyData +{ + public: + ~AnyData(); + AnyData(void *any) ; + AnyData(const Connection *sessp); + AnyData(const Connection *sessp, OCIAnyData *any, bool freeImg = true) ; + + AnyData(const AnyData &src); + AnyData& operator = (const AnyData &src); + + OCIAnyData* getOCIAnyData() const; + const Connection* getConnection() const; + + + bool isNull() const ; + void setNull() ; + OCCI_STD_NAMESPACE::string getString() const ; + UString getUString() const ; + Blob getBlob() const ; + Clob getClob() const ; + Bfile getBfile() const ; + BFloat getBFloat() const ; + BDouble getBDouble() const ; + Number getNumber() const ; + Bytes getBytes() const ; + Date getDate() const ; + Timestamp getTimestamp() const ; + IntervalYM getIntervalYM() const ; + IntervalDS getIntervalDS() const ; + PObject *getObject(void *(*rSQL)(void *)) const ; + RefAny getRef() const ; + + void setString(const OCCI_STD_NAMESPACE::string &str) ; + void setUString(const UString &str) ; + void setBlob(const Blob &blob) ; + void setClob(const Clob &clob) ; + void setBfile(const Bfile &bfile) ; + void setBFloat(const BFloat &n) ; + void setBDouble(const BDouble &n) ; + void setNumber(const Number &n) ; + void setBytes(const Bytes &bytes) ; + void setDate(const Date &date) ; + void setTimestamp(const Timestamp ×tamp) ; + void setIntervalYM(const IntervalYM &intervalym) ; + void setIntervalDS(const IntervalDS &intervalds) ; + void setObject(const PObject *objptr) ; + void setRef(const RefAny &ref) ; + + void setFromString(const OCCI_STD_NAMESPACE::string &str) ; + void setFromBfile(const Bfile &bfile) ; + void setFromBFloat(const BFloat &n) ; + void setFromBDouble(const BDouble &n) ; + void setFromNumber(const Number &n) ; + void setFromBytes(const Bytes &bytes) ; + void setFromDate(const Date &date) ; + void setFromTimestamp(const Timestamp ×tamp) ; + void setFromIntervalYM(const IntervalYM &intervalym) ; + void setFromIntervalDS(const IntervalDS &intervalds) ; + void setFromObject(const PObject *objptr) ; + void setFromRef(const RefAny &ref, + const OCCI_STD_NAMESPACE::string &typname, + const OCCI_STD_NAMESPACE::string &schname) ; + + OCCI_STD_NAMESPACE::string getAsString() const ; + Bfile getAsBfile() const ; + BFloat getAsBFloat() const ; + BDouble getAsBDouble() const ; + Number getAsNumber() const ; + Bytes getAsBytes() const ; + Date getAsDate() const ; + Timestamp getAsTimestamp() const ; + IntervalYM getAsIntervalYM() const ; + IntervalDS getAsIntervalDS() const ; + PObject *getAsObject() const ; + RefAny getAsRef() const ; + + TypeCode getType() const; + + private: + + + // private data members + Ptr anyDataImplPtr; + + +}; + +template +class Ref +{ + public: + + Ref(); + Ref(const T *obj) ; + Ref(const RefAny &refAny) ; + Ref(const Ref &src) ; + Ref(const Connection *sessp, OCIRef *tref, bool copy=TRUE) + ; + ~Ref(); + Ref& operator=(const Ref &src) + ; + Ref& operator=(const T *obj) ; + Ref& operator=(const RefAny &src); + T * operator->() ; + T * ptr() ; + T & operator *() ; + const T * operator->() const; + const T * ptr() const; + const T & operator *() const ; + void markDelete() ; + void unmarkDelete() ; + void setNull(); + bool isNull() const; + void clear() ; + bool isClear() const; + void setPrefetch(const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth); + void setPrefetch(const OCCI_STD_NAMESPACE::string &schName, + const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth); + void setPrefetch(const UString &schName, + const UString &typeName, + unsigned int depth); + void setPrefetch(unsigned int depth) ; + void setLock(LockOptions ); + operator RefAny() const; + OCIRef *getRef() const; + const Connection *getConnection() const; + bool operator == (const Ref &ref) const; + bool operator != (const Ref &ref) const; + bool operator == (const RefAny &refAnyR) const ; + bool operator != (const RefAny &refAnyR) const ; + OCIComplexObject *getCor() const; + void setPinnedObject(PObject *objPtr); + private: + + RefImpl *rimplPtr; +}; + + +class RefImpl +{ + public: + + RefImpl(); + RefImpl(PObject *obj) ; + RefImpl(const RefAny &refAny) ; + RefImpl(const RefImpl &src) ; + RefImpl(const Connection *sessp, OCIRef *tref, + bool copy=TRUE) ; + ~RefImpl(); + bool isNull() const ; + void setNull() ; + void markDelete() ; + void unmarkDelete() ; + void clear() ; + bool isClear() const ; + void setPrefetch(const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth) ; + void setPrefetch(const OCCI_STD_NAMESPACE::string &schName, + const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth); + void setPrefetch(const UString &schName, + const UString &typeName, + unsigned int depth); + void setPrefetch(unsigned int depth) ; + void setLock(LockOptions lckOption) ; + PObject *pin() ; + void unpin(PObject *obj) ; + void setRefFromObjPtr(const PObject *obj) ; + OCIRef* getRef() const; + void setRefImpl(RefImpl *rptr); + const Connection * getConnection() const; + bool operator == (const RefImpl &refI) const ; + bool operator == (const RefAny &refAnyR) const ; + void assignObj(PObject *newObjPtr) ; + void assignRefAny(const RefAny &src) ; + // added following methods + bool isEqual(PObject *obj); + void operator = ( const RefImpl &src); + OCIComplexObject *getCor() const; + void setPinnedObject( PObject *objPtr); + private: + + OCIRef *ref; + const ConnectionImpl *sessp; + OCIComplexObject *corhp; + OCCI_STD_NAMESPACE::list descriptorList; + LockOptions lockOption; + // added data member for object header + void *objHeader; + //common implementation function for setPrefetch + void do_setPrefetch(void *schName, unsigned int schNameLen, + void *typeName, unsigned int typeNameLen, + unsigned int depth); +}; + + +class RefAny +{ + public: + + RefAny(); + RefAny (const Connection *sessptr, const OCIRef *ref); + RefAny (const Connection *sessptr, const OCIRef *ref, bool isowner); + ~RefAny() ; + RefAny(const RefAny& src) ; + RefAny& operator=(const RefAny& src) ; + void markDelete() ; + void unmarkDelete() ; + void clear() ; + bool isNull() const; + OCIRef * getRef() const; + const Connection * getConnection() const; + bool operator == (const RefAny &refAnyR) const; + bool operator != (const RefAny &refAnyR) const; + bool isOwner() const; + + private: + + OCIRef *ref; + const ConnectionImpl *sessp; + // for future use + void *refanyExt; + bool owner; + + friend RefAny MetaData::getRef(MetaData::AttrId) const; + friend RefAny PObject::getRef() const; + friend class AnyDataImpl; + friend class ResultSetImpl; + friend class StatementImpl; + friend void getVector(const ResultSet *rs, + unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(const Statement *stmt, + unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect) ; +}; + +template +Ref::Ref() +{ + rimplPtr = new RefImpl(); +} + +template +Ref::Ref(const T *obj) +{ + rimplPtr = new RefImpl((PObject *)obj); +} + +template +Ref::Ref(const RefAny &refAny) + +{ + rimplPtr = new RefImpl(refAny); +} + +template +Ref::Ref(const Ref& src) + +{ + rimplPtr = new RefImpl(*(src.rimplPtr)); +} + +template +Ref::Ref(const Connection *sessp, OCIRef *tref, bool copy) + +{ + rimplPtr = new RefImpl(sessp, tref, copy); +} + +template +Ref::~Ref() +{ + delete rimplPtr; +} + + +template +Ref& Ref::operator=(const Ref &src) +{ + if (&src == this) + return *this; + *rimplPtr = *(src.rimplPtr); + return *this; +} + +template +Ref& Ref::operator=(const T *obj) +{ + if (rimplPtr->isEqual((PObject *)obj)) + return *this; + rimplPtr->assignObj((PObject *)obj); + return *this; +} + +template +Ref& Ref::operator=(const RefAny &src) +{ + rimplPtr->assignRefAny(src); + return *this; +} + +template +T* Ref::operator->() +{ + return ((T *)rimplPtr->pin()); +} + +template +T* Ref::ptr() +{ + return ((T *)rimplPtr->pin()); +} + +template +T& Ref::operator * () +{ + return ((T &)(*(rimplPtr->pin()))); +} + +template +const T* Ref::operator->() const +{ + return ((const T *)rimplPtr->pin()); +} + +template +const T* Ref::ptr() const +{ + return ((const T *)rimplPtr->pin()); +} + +template +const T& Ref::operator * () const +{ + return ((const T &)(*(rimplPtr->pin()))); +} + +template +void Ref::markDelete () +{ + rimplPtr->markDelete(); +} + +template +void Ref::unmarkDelete () +{ + rimplPtr->unmarkDelete(); +} + +template +void Ref::setNull() +{ + rimplPtr->setNull(); +} + +template +bool Ref::isNull() const +{ + return rimplPtr->isNull(); +} + +template +void Ref::clear () +{ + rimplPtr->clear(); +} + +template +bool Ref::isClear() const +{ + return rimplPtr->isClear(); +} + +template +void Ref::setPrefetch (const OCCI_STD_NAMESPACE::string &typeName, +unsigned int depth) + +{ + rimplPtr->setPrefetch(typeName,depth); +} + +template +void Ref::setPrefetch (const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName, +unsigned int depth) + +{ + rimplPtr->setPrefetch(schemaName,typeName,depth); +} + +template +void Ref::setPrefetch (const UString &schemaName, +const UString &typeName, +unsigned int depth) + +{ + rimplPtr->setPrefetch(schemaName,typeName,depth); +} + +template +void Ref::setPrefetch (unsigned int depth) + +{ + rimplPtr->setPrefetch(depth); +} + +template +void Ref::setLock (LockOptions lckOption) +{ + rimplPtr->setLock(lckOption); +} + +template +OCIRef* Ref::getRef() const +{ + return (rimplPtr->getRef()); +} + +template +const Connection* Ref::getConnection () const +{ + return (rimplPtr->getConnection()); +} + +template +Ref::operator RefAny () const +{ + if (isNull()) + return RefAny(); + return (RefAny(rimplPtr->getConnection(), rimplPtr->getRef())); +} + +template +bool Ref::operator ==(const Ref &ref) const + +{ + return ( (*rimplPtr) == (*(ref.rimplPtr)) ); +} + +template +bool Ref::operator !=(const Ref &ref) const + +{ + return ( !((*rimplPtr) == (*(ref.rimplPtr))) ); +} + +template +bool Ref::operator == (const RefAny & refAnyR) const + +{ + return ( (*rimplPtr) == refAnyR ); +} + +template +bool Ref::operator != (const RefAny & refAnyR) const + +{ + return ( !((*rimplPtr) == refAnyR )); +} + +template +OCIComplexObject * Ref::getCor() const +{ + return (rimplPtr->getCor()); +} + +template < class T> +void Ref::setPinnedObject( PObject *objPtr) +{ + rimplPtr->setPinnedObject(objPtr); +} + +/*--------------------------------------------------------------------------- + PROTOTYPES USED BY FUNCTION TEMPLATES + ---------------------------------------------------------------------------*/ + void getVectorOfOCIRefs( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVectorOfPObjects( const AnyData &any, + OCCI_STD_NAMESPACE::vector< PObject* > &vect, + void *(*rSQL)(void *)) ; + void setVectorOfOCIRefs( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector< OCIInd> &vec_ind) ; + void setVectorOfPObjects( AnyData &any, + const OCCI_STD_NAMESPACE::vector< PObject* > &vect) ; + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------- getVector for POBject----------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the + current position as a vector of PObject + + PARAMETERS + any - AnyData + vect- reference to vector of PObject (OUT parameter). + + DESCRIPTION + Retrieves the attribute in the current position as a vector + of PObject + The attribute at the current position should be a collection + type (varray or nested table). The SQL type of the elements in + the collection should be compatible with PObject + + RETURNS + nothing + + NOTES + compatible SQL types : user defined types (SQLT_NTY) etc. +*/ + +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + template + void getVector(const AnyData &any, OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + getVectorOfPObjects( any, vec_pobj, rSQL); + + vect.clear(); + unsigned int size= vec_pobj.size(); + vect.reserve( size ); + for( unsigned int i=0; i< size; i++) + vect.push_back( (T)vec_pobj[i] ); + } +#else + template + void getVector(const AnyData &any, OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + getVectorOfPObjects( any, vec_pobj, rSQL); + + vect.clear(); + unsigned int size= vec_pobj.size(); + vect.reserve( size ); + for( unsigned int i=0; i< size; i++) + vect.push_back( (T*)vec_pobj[i] ); + } +#endif /* end of #ifdef WIN32COMMON */ + + /*------------------- getVector for Ref----------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the + current position as a vector of PObject + + PARAMETERS + any - AnyData + vect- reference to vector of PObject (OUT parameter). + + DESCRIPTION + Retrieves the attribute in the current position as a vector + of PObject + The attribute at the current position should be a collection + type (varray or nested table). The SQL type of the elements in + the collection should be compatible with PObject + + RETURNS + nothing + + NOTES + compatible SQL types : user defined types (SQLT_NTY) etc. +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(const AnyData &any,OCCI_STD_NAMESPACE::vector< Ref > &vect) + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + getVectorOfOCIRefs( any, vec_ref); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + const Connection *sess = any.getConnection(); + + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } + } +#endif /* end of #ifndef WIN32COMMON */ + +/*-----------------------setVector for PObject--------------------------*/ +/* + NAME + setVector - overloaded function. sets the attribute in the current + position of anydata with the vector elements. + + PARAMETERS + none. + + DESCRIPTION + sets the attribute in the current position in anydata with the + vector elements. + The attribute in the current position of anydata should be a + collection type. If the collection type is a varray, the input vector + size should be equal to the size of the varray. Also the SQL type of + the collection's elements should be compatible with PObject. + + RETURNS + nothing. + + NOTES + compatible SQL types : SQLT_NTY (user defined types). +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + + template + void setVector(AnyData &any, const OCCI_STD_NAMESPACE::vector &vect) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + unsigned int size= vect.size(); + vec_pobj.reserve( size ); + for( unsigned int i=0; i< size; i++) + vec_pobj.push_back( vect[i] ); + setVectorOfPObjects( any, vec_pobj); + + } + +#else + + template + void setVector(AnyData &any, const OCCI_STD_NAMESPACE::vector &vect) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + unsigned int size= vect.size(); + vec_pobj.reserve( size ); + for( unsigned int i=0; i< size; i++) + vec_pobj.push_back( vect[i] ); + setVectorOfPObjects( any, vec_pobj); + + } +#endif /* end of #ifdef WIN32COMMON */ + +/*-----------------------setVector for Ref--------------------------*/ +/* + NAME + setVector - overloaded function. sets the attribute in the current + position of anydata with the vector elements. + + PARAMETERS + none. + + DESCRIPTION + sets the attribute in the current position in anydata with the + vector elements. + The attribute in the current position of anydata should be a + collection type. If the collection type is a varray, the input vector + size should be equal to the size of the varray. Also the SQL type of + the collection's elements should be compatible with PObject. + + RETURNS + nothing. + + NOTES + compatible SQL types : SQLT_NTY (user defined types). +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(AnyData &any, const OCCI_STD_NAMESPACE::vector< Ref > &vect) + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + + unsigned int size= vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + for( unsigned int i=0; i< size; i++) + { + vec_ref.push_back( vect[i].getRef() ); + vec_ind.push_back(vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + setVectorOfOCIRefs( any, vec_ref, vec_ind); + + } +#endif /* end of #ifndef WIN32COMMON */ + +// Platform independent get/setVectorOfRefs method added +// get(set)Vector of Ref and get(set)VectorOfRefs are identical +// in functionality. + + /*------------------- getVectorOfRefs for Ref----------------------------*/ +/* + NAME + getVectorOfRefs - overloaded function. Retrieves the attribute in the + current position as a vector of PObject + + PARAMETERS + any - AnyData + vect- reference to vector of PObject (OUT parameter). + + DESCRIPTION + Retrieves the attribute in the current position as a vector + of PObject + The attribute at the current position should be a collection + type (varray or nested table). The SQL type of the elements in + the collection should be compatible with PObject + + RETURNS + nothing + + NOTES + compatible SQL types : user defined types (SQLT_NTY) etc. +*/ + + template + void getVectorOfRefs(const AnyData &any, + OCCI_STD_NAMESPACE::vector< Ref > &vect) + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + getVectorOfOCIRefs( any, vec_ref); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + const Connection *sess = any.getConnection(); + + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } + } + +/*-----------------------setVectorOfRefs for Ref--------------------------*/ +/* + NAME + setVectorOfRefs - overloaded function. sets the attribute in the current + position of anydata with the vector elements. + + PARAMETERS + none. + + DESCRIPTION + sets the attribute in the current position in anydata with the + vector elements. + The attribute in the current position of anydata should be a + collection type. If the collection type is a varray, the input vector + size should be equal to the size of the varray. Also the SQL type of + the collection's elements should be compatible with PObject. + + RETURNS + nothing. + + NOTES + compatible SQL types : SQLT_NTY (user defined types). +*/ + + template + void setVectorOfRefs(AnyData &any, + const OCCI_STD_NAMESPACE::vector< Ref > &vect) + + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + + unsigned int size= vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + for( unsigned int i=0; i< size; i++) + { + vec_ref.push_back( vect[i].getRef() ); + vec_ind.push_back(vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + setVectorOfOCIRefs( any, vec_ref, vec_ind); + + } + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +} /* end of namespace occi */ +} /* end of namespace oracle */ +#endif /* OCCIOBJECTS_ORACLE */ + +#endif /* _olint */ diff --git a/OCI/include/oci.h b/OCI/include/oci.h new file mode 100644 index 0000000..7984141 --- /dev/null +++ b/OCI/include/oci.h @@ -0,0 +1,3045 @@ +/* Copyright (c) 1995, 2009, Oracle and/or its affiliates. +All rights reserved. */ + +/* + NAME + oci.h - V8 Oracle Call Interface public definitions + + DESCRIPTION + This file defines all the constants and structures required by a V8 + OCI programmer. + + RELATED DOCUMENTS + V8 OCI Functional Specification + Oracle Call Interface Programmer's Guide Vol 1 and 2 + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + None + + PRIVATE FUNCTION(S) + None + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + ssahu 04/15/09 - Add user handle as an attribute to session pool + handle + dalpern 03/17/09 - bug 7646876: applying_crossedition_trigger + kneel 11/21/08 - bump OCI version to 11.2 + thoang 09/24/08 - include ocixstream.h + asohi 08/25/08 - Bug 7320582 : AQ dequeue navigation flags fix + thoang 08/04/08 - Add XStream attributes + msowdaga 07/23/08 - Add flag OCI_SESSGET_SYSDBA + rphillip 03/21/08 - Add partition memory attribute + nikeda 04/15/08 - Support OCIP_ATTR_CONTYPE + mbastawa 12/24/07 - add server, envhp attributes + slynn 03/18/08 - + amullick 02/11/08 - add support for OCILobGet/SetContentType + tbhosle 01/07/08 - add OCI_ATTR_SUBSCR_IPADDR + nikeda 12/19/07 - Add OCI_SUBSCR_QOS_HAREG + rphillip 10/22/07 - Add OCI_ATTR_DIRPATH_NO_INDEX_ERRORS + debanerj 12/14/07 - Added OCI_ATTR_RESERVED_38 and OCI_ATTR_RESERVED_39 + umabhat 09/20/07 - bug6119750 added OCI_FNCODE_APPCTXSET & + OCI_FNCODE_APPCTXCLEARALL + debanerj 04/10/07 - XDS Attributes + msakayed 05/24/07 - Bug #5095734: add OCI_ATTR_DIRPATH_RESERVED_19 + schoi 03/02/07 - Get/SetOptions API change + ebatbout 03/30/07 - 5598333: Add OCI_ATTR_DIRPATH_RESERVED_18 + nikeda 03/21/07 - Add OCI_ATTR_RESERVED_37 + abande 03/06/07 - Remove attributes for global stmt cache and + metadata cache + rphillip 02/20/07 - Add OCI_ATTR_DIRPATH_RESERVED_17 + shan 11/16/06 - bug 5595911. + msakayed 12/04/06 - Bug #5660845: add OCI_DIRPATH_INPUT_OCI + gviswana 10/26/06 - Remove OCI_ATTR_CURRENT_EDITION + maramali 09/29/06 - bug 5568492, added OCI_NLS_LOCALE_A2_ISO_2_ORA + gviswana 09/29/06 - CURRENT_EDITION -> EDITION + aramappa 09/20/06 - Update major and minor version information + slynn 07/28/06 - Migrate to new 11g LOB terminiology + debanerj 07/20/06 - Add OCI_ATTR_LOBPREFETCH_LENGTH + mbastawa 06/25/06 - add OCI_ATTR_RESERVED_36 + hqian 05/22/06 - 11gR1 proj-18303: add OCI_SYSASM + dkogan 04/06/06 - disable charset validation by default + jhealy 05/15/06 - Add TimesTen OCI adapter. + slynn 06/20/06 - GetSharedRegions + rthammai 06/13/06 - add reserved attribute + msakayed 06/15/06 - Project 20586: interval partitioning support + debanerj 10/25/05 - LOB prefetch + slynn 05/25/06 - New NG Lob Functionality. + yujwang 05/16/06 - Add OCI_ATTR_RESERVED_33, OCI_ATTR_RESERVED_34 + abande 04/25/06 - 18297: Add attributes for global stmt cache and + metadata cache + ssvemuri 04/26/06 - Constants for Query Notification support + jgiloni 05/05/06 - Add OCI_ATCH_RESERVED_7 + mxyang 02/01/06 - Added OCI_ATTR_CURRENT_EDITION attribute + hqian 05/04/06 - new runtime capability attribute for asm volume + nikeda 06/06/06 - OCI_TT: Add new OCIP attributes + aramappa 04/17/06 - Added OCI_FNCODE_ARRAYDESCRIPTORALLOC and + OCI_FNCODE_ARRAYDESCRIPTORFREE + debanerj 05/04/06 - 18313: OCI Net Fusion + rupsingh 05/26/06 - + jacao 05/11/06 - + absaxena 04/17/06 - add notification grouping attributes + rpingte 02/02/06 - add OCI_ATCH_RESERVED_6 + rpingte 04/27/06 - Add OCI_ATTR_DRIVER_NAME + jawilson 02/14/06 - add OCI_FNCODE_AQENQSTREAM + kneel 04/03/06 - Adding support in kjhn for critical severity + rphillip 03/31/06 - Add OCI_ATTR_DIRPATH_RESERVED_14 + mxyang 02/01/06 - Added OCI_ATTR_APPLICATION_EDITION attribute + rphillip 01/30/06 - Add new DPAPI attrs + ebatbout 11/03/05 - Add direct path support for multiple subtypes + porangas 02/22/06 - 5055398: Define OCI_STMT_CALL + mbastawa 01/31/06 - add OCI_ATTR_RESERVED_26 + yohu 01/27/06 - align Execution Modes macros + sjanardh 01/25/06 - add OCI_EXEC_RESERVED_6 + sichandr 01/18/06 - add OCI_ATTR_XMLTYPE_BINARY_XML + yohu 12/22/05 - add OCI_TRANS_PROMOTE + srseshad 09/12/05 - stmtcache: callback + krajan 10/25/05 - Added ENABLE_BEQUEATH attach flag + mbastawa 09/16/05 - dbhygiene + porangas 07/20/04 - 1175350: adding attribute for ognfd + chliang 06/30/05 - add OCI_SUPPRESS_NLS_VALIDATION mode + aahluwal 03/15/05 - [Bug 4235014]:add ASM, Preconnect events + ssappara 08/12/04 - Bug3669429 add OCI_ATTR_DESC_SYNBAS + absaxena 03/24/05 - remove OCI_AQ_RESERVED_5 + mbastawa 03/01/05 - add OCI_EXEC_RESERVED_5 + msakayed 02/15/05 - Bug #3147299: Add OCI_ATTR_CURRENT_ERRCOL + aahluwal 01/11/05 - [Bug 3944589]: add OCI_AUTH_RESERVED_5 + nikeda 11/15/04 - Add OCIP_IIO + rvissapr 11/10/04 - bug 3843644 - isencrypted + hohung 11/22/04 - add OCI_BIND_RESERVED_3 + cchui 10/25/04 - add OCI_ATTR_PROXY_CLIENT + aahluwal 09/27/04 - add incarnation, reason, cardinality to event handle + msakayed 09/14/04 - column encryption support (project id 5578) + jacao 08/17/04 - Add OCI_ATTR_DB_CHARSET_ID + mhho 08/29/04 - resolve conflicting mode declaration + sgollapu 05/28/04 - Add OCI_AUTH_RESERVED_3 + mbastawa 08/05/04 - add OCI_ATTR_RESERVED_21 + ebatbout 07/27/04 - add OCI_ATTR_DIRPATH_RESERVED_9 and move all direct + path attributes into a separate area in this file. + clei 06/29/04 - add OCI_ATTR_ENCC_SIZE + weiwang 05/06/04 - add OCIAQListenOpts and OCIAQLisMsgProps + weiwang 04/30/04 - add OCI_AQ_RESERVED_5 + nbhatt 04/27/04 - add new attribute + ssvemuri 06/19/04 - change notification descriptors and attributes + ksurlake 06/01/04 - grabtrans 'ksurlake_txn_skmishra_clone' + ksurlake 05/13/04 - add subscriber handle attributes + mbastawa 06/01/04 - add 3 more OCI_FETCH_RESERVED modes + chliang 05/28/04 - add nchar literal replacement modes + nikeda 05/14/04 - [OLS on RAC] new authentication mode + debanerj 05/17/04 - 13064: add fncodes for LOB array Read and Write + nikeda 05/20/04 - [OCI Events] Add incarnation, cardinality,reason + nikeda 05/18/04 - [OCI Events] Add OCI_ATTR_SERVICENAME + nikeda 05/17/04 - Add event handle + nikeda 05/13/04 - [OCI Events] Rename HACBK->EVTCBK, HACTX->EVTCTX + nikeda 05/10/04 - [OCI Events] code review changes + nikeda 04/15/04 - [OCI Events] OCI_SESSRLS_DROPSESS_FORCE + nikeda 04/12/04 - [OCI Events] Add OCI_ATTR_USER_MEMORY + aahluwal 04/12/04 - add OCI_HNDLFR_RESERVED5 + vraja 04/28/04 - add options for redo sync on commit + aahluwal 05/29/04 - [OCI Events]: add support for svc, svc member events + nikeda 05/28/04 - grabtrans 'nikeda_oci_events_copy' + nikeda 05/18/04 - [OCI Events] Add OCI_ATTR_SERVICENAME + nikeda 05/17/04 - Add event handle + nikeda 05/13/04 - [OCI Events] Rename HACBK->EVTCBK, HACTX->EVTCTX + nikeda 05/10/04 - [OCI Events] code review changes + nikeda 04/15/04 - [OCI Events] OCI_SESSRLS_DROPSESS_FORCE + nikeda 04/12/04 - [OCI Events] Add OCI_ATTR_USER_MEMORY + aahluwal 04/12/04 - add OCI_HNDLFR_RESERVED5 + jciminsk 04/28/04 - merge from RDBMS_MAIN_SOLARIS_040426 + jacao 03/06/04 - add OCI_ATTR_CURRENT_SCHEMA + aahluwal 01/20/04 - remove OCI_KEEP_FETCH_STATE + aahluwal 03/25/04 - [OCI Events] add OCI_HTYPE_HAEVENT and related attrs + nikeda 03/19/04 - [OCI Events] Add OCI_ATTR_HACBK and OCI_ATTR_HACTX + dfrumkin 12/04/03 - Add database startup/shutdown + chliang 12/22/03 - grid/main merge: add OCI_ATTR_RESERVED_20 + jciminsk 12/12/03 - merge from RDBMS_MAIN_SOLARIS_031209 + sgollapu 09/19/03 - Add fetch modes + sgollapu 07/30/03 - Add TSM attributes + sgollapu 06/26/03 - Add OCI_MUTEX_TRY + aime 06/23/03 - sync grid with main + sgollapu 06/07/03 - Add reserved attribute + sgollapu 06/05/03 - Add reserved auth flag + rpingte 05/22/03 - Add OCI_ATCH_RESERVED_5 + sgollapu 05/06/03 - Add TSM attributes + sgollapu 04/10/03 - Session migration Flags/interfaces + dfrumkin 04/23/04 - add OCI_PREP2_RESERVED_1 + rpingte 05/06/04 - add major and minor version information + bsinha 04/06/04 - add new OCI_TRANS flag + chliang 11/26/03 - add OCI_ATTR_RESERVED_19 + preilly 10/23/03 - Make OCI_ATTR_DIRPATH_METADATA_BUF private + chliang 08/07/03 - add OCI_ATTR_SKIP_BUFFER + srseshad 03/12/03 - convert public oci api to ansi + weiwang 05/14/03 - remove iot creation for rule sets + rkoti 04/15/03 - [2746515] add fntcodes for Unlimited size LOB 6003 + tcruanes 05/13/03 - add slave SQL OCI execution mode + rkoti 02/21/03 - [2761455] add OCI_FNCODE_AQENQARRAY, + OCI_FNCODE_AQDEQARRAY and update OCI_FNCODE_MAXFCN + tkeefe 01/29/03 - bug-2773794: Add new interface for setting Kerb attrs + aahluwal 02/06/03 - add OCI_ATTR_TRANSFORMATION_NO + weiwang 12/05/02 - add OCI_ATTR_USER_PROPERTY + ataracha 01/03/03 - include ocixmldb.h + preilly 12/05/02 - Add wait attribute for locking when using dir path + tkeefe 01/03/03 - bug-2623771: Added OCI_ATTR_KERBEROS_KEY + lchidamb 12/13/02 - end-to-end tracing attributes + msakayed 10/28/02 - Bug #2643907: add OCI_ATTR_DIRPATH_SKIPINDEX_METHOD + rphillip 11/13/02 - Add OCIP_ATTR_DIRPATH_INDEX + sagrawal 10/13/02 - liniting + sagrawal 10/03/02 - PL/SQL Compiler warnings + jstenois 11/07/02 - remove ocixad.h + chliang 10/21/02 - add OCI_ATTR_RESERVED_16,17 + hsbedi 10/30/02 - grabtrans 'jstenois_fix_xt_convert' + aahluwal 10/12/02 - add OCI_ATTR_AQ_NUM_E_ERRORS/OCI_ATTR_AQ_ERROR_INDEX + bdagevil 10/21/02 - add SQL analyze internal exec mode + csteinba 10/11/02 - add OCI_ATTR_RESERVED_16 + chliang 10/12/02 - add bind row callback attributes + preilly 10/25/02 - Add new reserved parameters + tkeefe 10/31/02 - bug-2623771: Added OCI_ATTR_AUDIT_SESSION_ID + csteinba 10/04/02 - Add OCI_ATTR_RESERVED_15 + mhho 10/11/02 - add new credential constant + thoang 09/25/02 - Add OCI_XMLTYPE_CREATE_CLOB + skaluska 10/07/02 - describe rules objects + csteinba 09/16/02 - Remove OCI_CACHE + gtarora 10/03/02 - OCI_ATTR_COL_SUBS => OCI_ATTR_OBJ_SUBS + msakayed 09/09/02 - Bug #2482469: add OCI_ATTR_DIRPATH_RESERVED_[3-6] + aahluwal 08/30/02 - adding dequeue across txn group + srseshad 04/24/02 - Add attribute OCI_ATTR_SPOOL_STMTCACHESIZE. + ebatbout 07/22/02 - Remove OCI_ATTR_RESERVED_11. + abande 01/17/02 - Bug 1788921; Add external attribute. + aahluwal 06/04/02 - bug 2360115 + pbagal 05/24/02 - Incorporate review comments + pbagal 05/22/02 - Introduce instance type attribute. + whe 07/01/02 - add OCI_BIND_DEFINE_SOFT flags + gtarora 07/01/02 - Add OCI_ATTR_COL_SUBS + tkeefe 05/30/02 - Add support for new proxy authentication credentials + dgprice 12/18/01 - bug 2102779 add reserved force describe + schandir 11/19/01 - add/modify modes. + schandir 11/15/01 - add OCI_SPC_STMTCACHE. + schandir 12/06/01 - change mode value of OCI_SPOOL. + msakayed 11/02/01 - Bug #2094292: add OCI_ATTR_DIRPATH_INPUT + dsaha 11/09/01 - add OCI_DTYPE_RESERVED1 + skabraha 11/05/01 - new method flag + skabraha 10/25/01 - another flag for XML + skabraha 10/11/01 - describe flags for subtypes + nbhatt 09/18/01 - new reserved AQ flags + celsbern 10/19/01 - merge LOG to MAIN + ksurlake 10/12/01 - add OCI_ATTR_RESERVED_13 + ksurlake 08/13/01 - add OCI_ATTR_RESERVED_12 + schandir 09/24/01 - Adding stmt caching + abande 09/04/01 - Adding session pooling + sagrawal 10/23/01 - add new bit for OCIPHandleFree + preilly 10/25/01 - Add support for specifying metadata on DirPathCtx + skabraha 09/24/01 - describe flags for XML type + schandir 09/24/01 - Adding stmt caching + abande 09/04/01 - Adding session pooling + stakeda 09/17/01 - add OCI_NLS_CHARSET_ID + whe 09/19/01 - add OCIXMLType create options + rpingte 09/11/01 - add OCI_MUTEX_ENV_ONLY and OCI_NO_MUTEX_STMT + cmlim 08/28/01 - mod datecache attrs to use same naming as dpapi attrs + wzhang 08/24/01 - Add new keywords for OCINlsNameMap. + rphillip 05/02/01 - Add date cache attributes + rphillip 08/22/01 - Add new stream version + ebatbout 04/13/01 - add definition, OCI_ATTR_RESERVED_11 + chliang 04/12/01 - add shortnames for newer oci funcation + wzhang 04/11/01 - Add new OCI NLS constants. + cmlim 04/13/01 - remove attrs not used by dpapi (151 & 152 avail) + rkambo 03/23/01 - bugfix 1421793 + cmlim 04/02/01 - remove OCI_ATTR_DIRPATH_{NESTED_TBL, SUBST_OBJ_TBL} + - note: attribute #s 186 & 205 available + whe 03/28/01 - add OCI_AFC_PAD_ON/OFF mode + preilly 03/05/01 - Add stream versioning support to DirPath context + schandir 12/18/00 - remove attr CONN_INCR_DELAY. + schandir 12/12/00 - change mode from OCI_POOL to OCI_CPOOL. + cbarclay 01/12/01 - add atribute for OCIP_ATTR_TMZ + whe 01/07/01 - add attributes related to UTF16 env mode + slari 12/29/00 - add blank line + slari 12/28/00 - OCI_ATTR_RESERVED_10 + whe 12/19/00 - add OCI_ENVCR_RESERVED3 + rpang 11/29/00 - Added OCI_ATTR_ORA_DEBUG_JDWP attribute + cmlim 11/28/00 - support substitutable object tables in dpapi + akatti 10/09/00 - [198379]:add OCIRowidToChar + sgollapu 10/11/00 - Add OCI_PREP_RESERVED_1 + sgollapu 08/27/00 - add attribute to get erroneous column + sgollapu 07/29/00 - Add snapshot attributes + kmohan 09/18/00 - add OCI_FNCODE_LOGON2 + abrumm 10/08/00 - include ocixad.h + mbastawa 10/04/00 - add OCI_ATTR_ROWS_FETCHED + nbhatt 08/24/00 - add transformation attribute + dmwong 08/22/00 - OCI_ATTR_CID_VALUE -> OCI_ATTR_CLIENT_IDENTIFIER. + cmlim 08/30/00 - add OCI_ATTR_DIRPATH_SID + dsaha 08/18/00 - add OCI_ATTR_RESERVED_5 + amangal 08/17/00 - Merge into 8.2 : 1194361 + slari 08/03/00 - add OCI_ATTR_HANDLE_POSITION + dsaha 07/20/00 - 2rt exec + sgollapu 07/04/00 - Add virtual session flag + cmlim 07/07/00 - add OCI_ATTR_DIRPATH_OID, OCI_ATTR_DIRPATH_NESTED_TBL + etucker 07/28/00 - add OCIIntervalFromTZ + rwessman 06/26/00 - N-tier: added new credential attributes + whe 07/27/00 - add OCI_UTF16 mode + vjayaram 07/18/00 - add connection pooling changes + etucker 07/12/00 - add dls apis + cmlim 07/07/00 - add OCI_ATTR_DIRPATH_OID, OCI_ATTR_DIRPATH_NESTED_TBL + sgollapu 07/04/00 - Add virtual session flag + najain 05/01/00 - AQ Signature support + sgollapu 06/14/00 - Add reserved OCI mode + rkambo 06/08/00 - notification presentation support + sagrawal 06/04/00 - ref cursor to c + ksurlake 06/07/00 - define OCI_POOL + mbastawa 06/05/00 - added scrollable cursor attributes + weiwang 03/31/00 - add LDAP support + whe 05/30/00 - add OCI_ATTR_MAXCHAR_SIZE + whe 05/23/00 - validate OCI_NO_CACHE mode + dsaha 02/02/00 - Add no-cache attr in statement handle + whe 05/23/00 - add OCIP_ICACHE + allee 05/17/00 - describe support for JAVA implmented TYPE + preilly 05/30/00 - Continue adding support for objects in direct path lo + cmlim 05/16/00 - 8.2 dpapi support of ADTs + rxgovind 05/04/00 - OCIAnyDataSet changes + rkasamse 05/25/00 - add OCIAnyDataCtx + rmurthy 04/26/00 - describe support for inheritance + ksurlake 04/18/00 - Add credential type + whe 05/24/00 - add OCI_ATTR_CHAR_ attrs + rkambo 04/19/00 - subscription enhancement + rmurthy 04/26/00 - describe support for inheritance + delson 03/28/00 - add OCI_ATTR_RESERVED_2 + abrumm 03/31/00 - external table support + rkasamse 03/13/00 - add declarations for OCIAnyData + najain 02/24/00 - support for dequeue as select + dsaha 03/10/00 - Add OCI_ALWAYS_BLOCKING + esoyleme 04/25/00 - separated transactions + sgollapu 12/23/99 - OCIServerAttach extensions + slari 08/23/99 - add OCI_DTYPE_UCB + slari 08/20/99 - add OCI_UCBTYPE_REPLACE + hsbedi 08/31/99 - Memory Stats . + sgollapu 08/02/99 - oci sql routing + slari 08/06/99 - rename values for OCI_SERVER_STATUS + slari 08/02/99 - add OCI_ATTR_SERVER_STATUS + tnbui 07/28/99 - Remove OCI_DTYPE_TIMESTAMP_ITZ + amangal 07/19/99 - Merge into 8.1.6 : bug 785797 + tnbui 07/07/99 - Change ADJUSTMENT modes + dsaha 07/07/99 - OCI_SAHRED_EXT + dmwong 06/08/99 - add OCI_ATTR_APPCTX_* + vyanaman 06/23/99 - + vyanaman 06/21/99 - Add new OCI Datetime and Interval descriptors + esoyleme 06/29/99 - expose MTS performance enhancements + rshaikh 04/23/99 - add OCI_SQL_VERSION_* + tnbui 05/24/99 - Remove OCIAdjStr + dsaha 05/21/99 - Add OCI_ADJUST_UNK + mluong 05/17/99 - fix merge + tnbui 04/05/99 - ADJUSTMENT values + abrumm 04/16/99 - dpapi: more attributes + dsaha 02/24/99 - Add OCI_SHOW_DML_WARNINGS + jiyang 12/07/98 - Add OCI_NLS_DUAL_CURRENCY + slari 12/07/98 - change OCI_NOMUTEX to OCI_NO_MUTEX + aroy 11/30/98 - change OCI_NOCALLBACK to OCI_NO_UCB + aroy 11/13/98 - add env modes to process modes + slari 09/08/98 - add OCI_FNCODE_SVC2HST and _SVCRH + aroy 09/04/98 - Add OCI_ATTR_MIGSESSION + skray 08/14/98 - server groups for session switching + mluong 08/11/98 - add back OCI_HTYPE_LAST. + aroy 05/25/98 - add process handle type + aroy 04/06/98 - add shared mode + slari 07/13/98 - merge forward to 8.1.4 + slari 07/09/98 - add OCI_BIND_RESERVED_2 + slari 07/08/98 - add OCI_EXACT_FETCH_RESERVED_1 + dsaha 07/07/98 - Add OCI_PARSE_ONLY + dsaha 06/29/98 - Add OCI_PARSE_ONLY + slari 07/01/98 - add OCI_BIND_RESERVED_2 + sgollapu 06/25/98 - Fix bug 683565 + slari 06/17/98 - remove OC_FETCH_RESERVED_2 + slari 06/11/98 - add OCI_FETCH_RESERVED_1 and 2 + jhasenbe 05/27/98 - Remove definitions for U-Calls (Unicode) + jiyang 05/18/98 - remove OCI_ATTR_CARTLANG + nbhatt 05/20/98 - OCI_DEQ_REMOVE_NODATA + nbhatt 05/19/98 - correct AQ opcode + skmishra 05/06/98 - Add precision attribute to Attributes list + aroy 04/20/98 - merge forward 8.0.5 -> 8.1.3 + schandra 05/01/98 - OCI sender id + sgollapu 02/19/98 - enhanced array DML + nbhatt 05/15/98 - AQ listen call + sgollapu 04/27/98 - more attributes + skaluska 04/06/98 - Add OCI_PTYPE_SCHEMA, OCI_PTYPE_DATABASE + slari 04/28/98 - add OCI_ATTR_PDPRC + lchidamb 05/05/98 - change OCI_NAMESPACE_AQ to 1 + nbhatt 04/27/98 - AQ Notification Descriptor + abrumm 06/24/98 - more direct path attributes + abrumm 05/27/98 - OCI direct path interface support + abrumm 05/08/98 - OCI direct path interface support + lchidamb 03/02/98 - client notification additions + kkarun 04/17/98 - Add more Interval functions + vyanaman 04/16/98 - Add get/set TZ + kkarun 04/14/98 - Add OCI Datetime shortnames + vyanaman 04/13/98 - Add OCI DateTime and Interval check error codes + kkarun 04/07/98 - Add OCI_DTYPE_DATETIME and OCI_DTYPE_INTERVAL + esoyleme 12/15/97 - support failover callback retry + esoyleme 04/22/98 - merge support for failover callback retry + mluong 04/16/98 - add OCI_FNCODE_LOBLOCATORASSIGN + rkasamse 04/17/98 - add short names for OCIPickler(Memory/Ctx) cart servi + slari 04/10/98 - add OCI_FNCODE_SVCCTXTOLDA + slari 04/09/98 - add OCI_FNCODE_RESET + slari 04/07/98 - add OCI_FNCODE_LOBFILEISOPEN + slari 04/06/98 - add OCI_FNCODE_LOBOPEN + slari 03/20/98 - change OCI_CBTYPE_xxx to OCI_UCBTYPE_xxx + slari 03/18/98 - add OCI_FNCODE_MAXFCN + slari 02/12/98 - add OCI_ENV_NO_USRCB + skabraha 04/09/98 - adding shortnames for OCIFile + rhwu 04/03/98 - Add short names for the OCIThread package + tanguyen 04/03/98 - add OCI_ATTR_xxxx for type inheritance + rkasamse 04/02/98 - add OCI_ATTR_UCI_REFRESH + nramakri 04/01/98 - Add short names for the OCIExtract package + ewaugh 03/31/98 - Add short names for the OCIFormat package. + jhasenbe 04/06/98 - Add definitions for U-Calls (Unicode) + (OCI_TEXT, OCI_UTEXT, OCI_UTEXT4) + skmishra 03/03/98 - Add OCI_ATTR_PARSE_ERROR_OFFSET + rwessman 03/11/98 - Added OCI_CRED_PROXY for proxy authentication + abrumm 03/31/98 - OCI direct path interface support + nmallava 03/03/98 - add constants for temp lob apis + skotsovo 03/05/98 - resolve merge conflicts + skotsovo 02/24/98 - add OCI_DTYPE_LOC + skaluska 01/21/98 - Add OCI_ATTR_LTYPE + rkasamse 01/06/98 - add OCI_ATTR* for obj cache enhancements + dchatter 01/08/98 - more comments + skabraha 12/02/97 - moved oci1.h to the front of include files. + jiyang 12/18/97 - Add OCI_NLS_MAX_BUFSZ + rhwu 12/02/97 - move oci1.h up + ewaugh 12/15/97 - Add short names for the OCIFormat package. + rkasamse 12/02/97 - Add a constant for memory cartridge services -- OCI_M + nmallava 12/31/97 - open/close for internal lobs + khnguyen 11/27/97 - add OCI_ATTR_LFPRECISION, OCI_ATTR_FSPRECISION + rkasamse 11/03/97 - add types for pickler cartridge services + mluong 11/20/97 - changed ubig_ora to ub4 per skotsovo + ssamu 11/14/97 - add oci1.h + jiyang 11/13/97 - Add NLS service for cartridge + esoyleme 12/15/97 - support failover callback retry + jwijaya 10/21/97 - change OCILobOffset/Length from ubig_ora to ub4 + cxcheng 07/28/97 - fix compile with SLSHORTNAME + schandra 06/25/97 - AQ OCI interface + sgollapu 07/25/97 - Add OCI_ATTR_DESC_PUBLIC + cxcheng 06/16/97 - add OCI_ATTR_TDO + skotsovo 06/05/97 - add fntcodes for lob buffering subsystem + esoyleme 05/13/97 - move failover callback prototype + skmishra 05/06/97 - stdc compiler fixes + skmishra 04/22/97 - Provide C++ compatibility + lchidamb 04/19/97 - add OCI_ATTR_SESSLANG + ramkrish 04/15/97 - Add OCI_LOB_BUFFER_(NO)FREE + sgollapu 04/18/97 - Add OCI_ATTR_TABLESPACE + skaluska 04/17/97 - Add OCI_ATTR_SUB_NAME + schandra 04/10/97 - Use long OCI names + aroy 03/27/97 - add OCI_DTYPE_FILE + sgollapu 03/26/97 - Add OCI_OTYPEs + skmishra 04/09/97 - Added constant OCI_ROWID_LEN + dchatter 03/21/97 - add attr OCI_ATTR_IN_V8_MODE + lchidamb 03/21/97 - add OCI_COMMIT_ON_SUCCESS execution mode + skmishra 03/20/97 - Added OCI_ATTR_LOBEMPTY + sgollapu 03/19/97 - Add OCI_ATTR_OVRLD_ID + aroy 03/17/97 - add postprocessing callback + sgollapu 03/15/97 - Add OCI_ATTR_PARAM + cxcheng 02/07/97 - change OCI_PTYPE codes for type method for consistenc + cxcheng 02/05/97 - add OCI_PTYPE_TYPE_RESULT + cxcheng 02/04/97 - rename OCI_PTYPE constants to be more consistent + cxcheng 02/03/97 - add OCI_ATTR, OCI_PTYPE contants for describe type + esoyleme 01/23/97 - merge neerja callback + sgollapu 12/30/96 - Remove OCI_DTYPE_SECURITY + asurpur 12/26/96 - CHanging OCI_NO_AUTH to OCI_AUTH + sgollapu 12/23/96 - Add more attrs to COL, ARG, and SEQ + sgollapu 12/12/96 - Add OCI_DESCRIBE_ONLY + slari 12/11/96 - change prototype of OCICallbackInBind + nbhatt 12/05/96 - "callback" + lchidamb 11/19/96 - handle subclassing + sgollapu 11/09/96 - OCI_PATTR_* + dchatter 11/04/96 - add attr OCI_ATTR_CHRCNT + mluong 11/01/96 - test + cxcheng 10/31/96 - add #defines for OCILobLength etc + dchatter 10/31/96 - add lob read write call back fp defs + dchatter 10/30/96 - more changes + rhari 10/30/96 - Include ociextp.h at the very end + lchidamb 10/22/96 - add fdo attribute for bind/server handle + dchatter 10/22/96 - change attr defn for prefetch parameters & lobs/file + calls + slari 10/21/96 - add OCI_ENV_NO_MUTEX + rhari 10/25/96 - Include ociextp.h + rxgovind 10/25/96 - add OCI_LOBMAXSIZE, remove OCI_FILE_READWRITE + sgollapu 10/24/96 - Correct OCILogon and OCILogoff + sgollapu 10/24/96 - Correct to OCILogon and OCILogoff + sgollapu 10/21/96 - Add ocilon and ociloff + skaluska 10/31/96 - Add OCI_PTYPE values + sgollapu 10/17/96 - correct OCI_ATTR_SVCCTX to OCI_ATTR_SERVER + rwessman 10/16/96 - Added security functions and fixed olint errors. + sthakur 10/14/96 - add more COR attributes + cxcheng 10/14/96 - re-enable LOB functions + sgollapu 10/10/96 - Add ocibdp and ocibdn + slari 10/07/96 - add back OCIRowid + aroy 10/08/96 - add typedef ocibfill for PRO*C + mluong 10/11/96 - replace OCI_ATTR_CHARSET* with OCI_ATTR_CHARSET_* + cxcheng 10/10/96 - temporarily take out #define for lob functions + sgollapu 10/02/96 - Rename OCI functions and datatypes + skotsovo 10/01/96 - move orl lob fnts to oci + aroy 09/10/96 - fix merge errors + aroy 08/19/96 - NCHAR support + jboonleu 09/05/96 - add OCI attributes for object cache + dchatter 08/20/96 - HTYPE ranges from 1-50; DTYPE from 50-255 + slari 08/06/96 - define OCI_DTYPE_ROWID + sthakur 08/14/96 - complex object support + schandra 06/17/96 - Convert XA to use new OCI + abrik 08/15/96 - OCI_ATTR_HEAPALLOC added + aroy 07/17/96 - terminology change: ocilobd => ocilobl + aroy 07/03/96 - add lob typedefs for Pro*C + slari 06/28/96 - add OCI_ATTR_STMT_TYPE + lchidamb 06/26/96 - reorg #ifndef + schandra 05/31/96 - attribute types for internal and external client name + asurpur 05/30/96 - Changing the value of mode + schandra 05/18/96 - OCI_TRANS_TWOPHASE -> 0x00000001 to 0x00100000 + slari 05/30/96 - add callback function prototypes + jbellemo 05/23/96 - remove ociisc + schandra 04/23/96 - loosely-coupled branches + asurpur 05/15/96 - New mode for ocicpw + aroy 04/24/96 - making ocihandles opaque + slari 04/18/96 - add missing defines + schandra 03/27/96 - V8OCI - add transaction related calls + dchatter 04/01/96 - add OCI_FILE options + dchatter 03/21/96 - add oci2lda conversion routines + dchatter 03/07/96 - add OCI piece definition + slari 03/12/96 - add describe attributes + slari 03/12/96 - add OCI_OTYPE_QUERY + aroy 02/28/96 - Add column attributes + slari 02/09/96 - add OCI_OBJECT + slari 02/07/96 - add OCI_HYTPE_DSC + aroy 01/10/96 - adding function code defines... + dchatter 01/03/96 - define OCI_NON_BLOCKING + dchatter 01/02/96 - Add Any descriptor + dchatter 01/02/96 - Add Select List descriptor + dchatter 12/29/95 - V8 OCI definitions + dchatter 12/29/95 - Creation + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN +#include +#endif + +#ifndef OCI_ORACLE +# define OCI_ORACLE + + +/*--------------------------------------------------------------------------- + Short names provided for platforms which do not allow extended symbolic names + ---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME +/* Translation of the long function/type names to short names for IBM only */ +/* maybe lint will use this too */ +#define OCISessionEnd ocitac +#define OCIResultSetToStmt ocirs2sh +#define OCISessionBegin ociauth +#define OCIServerAttach ociatch +#define OCIDescriptorAlloc ocigdesc +#define OCIServerDetach ocidtch +#define OCIDescriptorFree ocifdesc +#define OCIServerVersion ocivers +#define OCIDescribeAny ocidsca +#define OCIBindDynamic ocibda +#define OCIBindByName ocibdn +#define OCIBindByPos ocibdp +#define OCIErrorGet ocigdr +#define OCIBindArrayOfStruct ocibsa +#define OCIEnvInit ociinit +#define OCIBindObject ocibndt +#define OCIHandleAlloc ocighndl +#define OCIHandleFree ocifhndl +#define OCIRowidToChar ociri2c +#ifdef NEVER +#define OCIStmtBindByPos ocibndp +#define OCIStmtBindByName ocibndn +#endif +#define OCIAttrGet ocigattr +#define OCIDefineByPos ocidfne +#define OCIAttrSet ocisattr +#define OCIDefineDynamic ociddf +#define OCILdaToSvcCtx ocild2sv +#define OCIDefineArrayOfStruct ocidarr +#define OCIInitialize ocipi +#define OCIDefineObject ocidndt +#define OCIStmtExecute ociexec +#define OCILobAppend ocilfap +#define OCILobOpenFile ocifopn +#define OCILobCloseFile ocifcls +#define OCILobLocator ocilobd +#define OCILobGetDeduplicateRegions ocilgshr +#define OCILobRegion ocilregd +#define OCILobCopy ocilfcp +#define OCILobFileCreate ocifcrt +#define OCILobFileDelete ocifdel +#define OCILobGetLength ocilfln +#define OCILobWrite ocilfwr +#define OCILobRead ocilfrd +#define OCILobErase ocilfer +#define OCILobTrim ocilftr +#define OCILobSetOptions ocinglso +#define OCILobGetOptions ocinglgo +#define OCILobFragmentInsert ocinglfi +#define OCILobFragmentDelete ocinglfd +#define OCILobFragmentMove ocinglfm +#define OCILobFragmentReplace ocinglfr +#define OCILobSetContentType ocinglsct +#define OCILobGetContentType ocinglgct + +#define OCIStmtFetch ocifch +#define OCIStmtGetBindInfo ocigbp +#define OCIStmtGetPieceInfo ocigpi +#define OCIStmtPrepare ocireq +#define OCIStmtSetPieceInfo ocispi +#define OCISvcCtxToLda ocisv2ld +#define OCITransCommit ocitxcm +#define OCITransDetach ocitxdt +#define OCITransForget ocitxfgt +#define OCITransPrepare ocitxpre +#define OCITransRollback ocitxrl +#define OCIPasswordChange ocicpw +#define OCITransStart ocitxst +#define OCITransMultiPrepare ocitxmp + +#define OCIBreak ocibreak +#define OCIParamGet ocigparm +#define OCIParamSet ocisparm + +#define OCISecurityOpenWallet ocizwOpenWallet +#define OCISecurityCloseWallet ocizwCloseWallet +#define OCISecurityCreateWallet ocizwCreateWallet +#define OCISecurityDestroyWallet ocizwDestroyWallet +#define OCISecurityStorePersona ocizeStorePersona +#define OCISecurityOpenPersona ocizeOpenPersona +#define OCISecurityClosePersona ocizeClosePersona +#define OCISecurityRemovePersona ocizeRemovePersona +#define OCISecurityCreatePersona ocizeCreatePersona +#define OCISecuritySetProtection ocizeSetProtection +#define OCISecurityGetProtection ocizeGetProtection +#define OCISecurityRemoveIdentity ociziRemoveIdentity +#define OCISecurityCreateIdentity ociziCreateIdentity +#define OCISecurityAbortIdentity ociziAbortIdentity +#define OCISecurityFreeIdentity ociziFreeIdentity +#define OCISecurityStoreTrustedIdentity ociziStoreTrustedIdentity +#define OCISecuritySign ocizSign +#define OCISecuritySignExpansion ocizxSignExpansion +#define OCISecurityVerify ocizVerify +#define OCISecurityValidate ocizValidate +#define OCISecuritySignDetached ocizsd_SignDetached +#define OCISecuritySignDetExpansion ocizxsd_SignDetachedExpansion +#define OCISecurityVerifyDetached ocizved_VerifyDetached +#define OCISecurity_PKEncrypt ocizkec_PKEncrypt +#define OCISecurityPKEncryptExpansion ocizxkec_PKEncryptExpansion +#define OCISecurityPKDecrypt ocizkdc_PKDecrypt +#define OCISecurityEncrypt ocizEncrypt +#define OCISecurityEncryptExpansion ocizxEncryptExpansion +#define OCISecurityDecrypt ocizDecrypt +#define OCISecurityEnvelope ocizEnvelope +#define OCISecurityDeEnvelope ocizDeEnvelope +#define OCISecurityKeyedHash ocizKeyedHash +#define OCISecurityKeyedHashExpansion ocizxKeyedHashExpansion +#define OCISecurityHash ocizHash +#define OCISecurityHashExpansion ocizxHashExpansion +#define OCISecuritySeedRandom ocizSeedRandom +#define OCISecurityRandomBytes ocizrb_RandomBytes +#define OCISecurityRandomNumber ocizrn_RandomNumber +#define OCISecurityInitBlock ocizibInitBlock +#define OCISecurityReuseBlock ocizrbReuseBlock +#define OCISecurityPurgeBlock ocizpbPurgeBlock +#define OCISecuritySetBlock ocizsbSetBlock +#define OCISecurityGetIdentity ocizgi_GetIdentity + +#define OCIExtractInit ocixeini +#define OCIExtractTerm ocixetrm +#define OCIExtractReset ocixerst +#define OCIExtractSetNumKeys ocixesnk +#define OCIExtractSetKey ocixesk +#define OCIExtractFromFile ocixeff +#define OCIExtractFromStr ocixefs +#define OCIExtractToInt ocixeti +#define OCIExtractToBool ocixetb +#define OCIExtractToStr ocixets +#define OCIExtractToOCINum ocixeton +#define OCIExtractToList ocixetl +#define OCIExtractFromList ocixefl + +#define OCIDateTimeGetTime ocidt01_GetTime +#define OCIDateTimeGetDate ocidt02_GetDate +#define OCIDateTimeGetTimeZoneOffset ocidt03_GetTZ +#define OCIDateTimeSysTimeStamp ocidt07_SysTS +#define OCIDateTimeAssign ocidt08_Assign +#define OCIDateTimeToText ocidt09_ToText +#define OCIDateTimeFromText ocidt10_FromText +#define OCIDateTimeCompare ocidt11_Compare +#define OCIDateTimeCheck ocidt12_Check +#define OCIDateTimeConvert ocidt13_Convert +#define OCIDateTimeSubtract ocidt14_Subtract +#define OCIDateTimeIntervalAdd ocidt15_IntervalAdd +#define OCIDateTimeIntervalSub ocidt16_IntervalSub +#define OCIDateTimeGetTimeZoneName ocidt17_Gettzname +#define OCIDateTimeToArray ocidt18_ToArray +#define OCIDateTimeFromArray ocidt19_FromArray + +#define OCIIntervalSubtract ociint01_Subtract +#define OCIIntervalAdd ociint02_Add +#define OCIIntervalMultiply ociint03_Multiply +#define OCIIntervalDivide ociint04_Divide +#define OCIIntervalCompare ociint05_Compare +#define OCIIntervalFromText ociint06_FromText +#define OCIIntervalToText ociint07_ToText +#define OCIIntervalToNumber ociint08_ToNumber +#define OCIIntervalCheck ociint09_Check +#define OCIIntervalAssign ociint10_Assign +#define OCIIntervalGetYearMonth ociint11_GetYearMonth +#define OCIIntervalSetYearMonth ociint12_SetYearMonth +#define OCIIntervalGetDaySecond ociint13_GetDaySecond +#define OCIIntervalSetDaySecond ociint14_SetDaySecond +#define OCIIntervalFromNumber ociint15_FromNumber +#define OCIIntervalFromTZ ociint16_FromTZ + +#define OCIFormatInit ocixs01_Init +#define OCIFormatString ocixs02_Format +#define OCIFormatTerm ocixs03_Term +#define OCIFormatTUb1 ocixs04_TUb1 +#define OCIFormatTUb2 ocixs05_TUb2 +#define OCIFormatTUb4 ocixs06_TUb4 +#define OCIFormatTUword ocixs07_TUword +#define OCIFormatTUbig_ora ocixs08_TUbig_ora +#define OCIFormatTSb1 ocixs09_TSb1 +#define OCIFormatTSb2 ocixs10_TSb2 +#define OCIFormatTSb4 ocixs11_TSb4 +#define OCIFormatTSword ocixs12_TSword +#define OCIFormatTSbig_ora ocixs13_TSbig_ora +#define OCIFormatTEb1 ocixs14_TEb1 +#define OCIFormatTEb2 ocixs15_TEb2 +#define OCIFormatTEb4 ocixs16_TEb4 +#define OCIFormatTEword ocixs17_TEword +#define OCIFormatTChar ocixs18_TChar +#define OCIFormatTText ocixs19_TText +#define OCIFormatTDouble ocixs20_TDouble +#define OCIFormatTDvoid ocixs21_TDvoid +#define OCIFormatTEnd ocixs22_TEnd + +#define OCIFileInit ocifinit +#define OCIFileTerm ocifterm +#define OCIFileOpen ocifopen +#define OCIFileClose ocifclose +#define OCIFileRead ocifread +#define OCIFileWrite ocifwrite +#define OCIFileSeek ocifseek +#define OCIFileExists ocifexists +#define OCIFileGetLength ocifglen +#define OCIFileFlush ocifflush + + +/* OCIThread short name */ +#define OCIThreadProcessInit ocitt01_ProcessInit +#define OCIThreadInit ocitt02_Init +#define OCIThreadTerm ocitt03_Term +#define OCIThreadIsMulti ocitt04_IsMulti +#define OCIThreadMutexInit ocitt05_MutexInit +#define OCIThreadMutexDestroy ocitt06_MutexDestroy +#define OCIThreadMutexAcquire ocitt07_MutexAcquire +#define OCIThreadMutexRelease ocitt08_MutexRelease +#define OCIThreadKeyInit ocitt09_KeyInit +#define OCIThreadKeyDestroy ocitt10_KeyDestroy +#define OCIThreadKeyGet ocitt11_KeyGet +#define OCIThreadKeySet ocitt12_KeySet +#define OCIThreadIdInit ocitt13_IdInit +#define OCIThreadIdDestroy ocitt14_IdDestroy +#define OCIThreadIdSet ocitt15_IdSet +#define OCIThreadIdSetNull ocitt16_IdSetNull +#define OCIThreadIdGet ocitt17_IdGet +#define OCIThreadIdSame ocitt18_IdSame +#define OCIThreadIdNull ocitt19_IdNull +#define OCIThreadHndInit ocitt20_HndInit +#define OCIThreadHndDestroy ocitt21_HndDestroy +#define OCIThreadCreate ocitt22_Create +#define OCIThreadJoin ocitt23_Join +#define OCIThreadClose ocitt24_Close +#define OCIThreadHandleGet ocitt25_HandleGet + +/* Translation between the old and new datatypes */ + +#define OCISession ociusrh +#define OCIBind ocibndh +#define OCIDescribe ocidsch +#define OCIDefine ocidfnh +#define OCIEnv ocienvh +#define OCIError ocierrh + +#define OCICPool ocicpool + +#define OCISPool ocispool +#define OCIAuthInfo ociauthinfo + + +#define OCILob ocilobd +#define OCILobLength ocillen +#define OCILobMode ocilmo +#define OCILobOffset ociloff + +#define OCILobLocator ocilobd +#define OCIBlobLocator ociblobl +#define OCIClobLocator ociclobl +#define OCILobRegion ocilregd +#define OCIBFileLocator ocibfilel + +#define OCIParam ocipard +#define OCIResult ocirstd +#define OCISnapshot ocisnad +#define OCIServer ocisrvh +#define OCIStmt ocistmh +#define OCISvcCtx ocisvch +#define OCITrans ocitxnh +#define OCICallbackInBind ocibicfp +#define OCICallbackOutBind ocibocfp +#define OCICallbackDefine ocidcfp +#define OCICallbackLobRead ocilrfp +#define OCICallbackLobWrite ocilwfp +#define OCICallbackLobGetDededuplicateRegions ocilgshr +#define OCISecurity ociossh +#define OCIComplexObject ocicorh +#define OCIComplexObjectComp ocicord +#define OCIRowid ociridd + +#define OCIAQDeq ociaqdeq +#define OCIAQEnq ociaqenq +#define OCIConnectionPoolCreate ociconpc +#define OCIConnectionPoolDestroy ociconpd +#define OCIEnvCreate ocienvct +#define OCILobAssign ociloass +#define OCILobCharSetForm ocilocfm +#define OCILobCharSetId ocilocid +#define OCILobDisableBuffering ocilodbf +#define OCILobEnableBuffering ociloebf +#define OCILobFileClose ocilofcl +#define OCILobFileCloseAll ocilofca +#define OCILobFileExists ocilofex +#define OCILobFileGetName ocilofgn +#define OCILobFileIsOpen ocifiopn +#define OCILobFileOpen ocilofop +#define OCILobFileSetName ocilofsn +#define OCILobFlushBuffer ocilofbf +#define OCILobIsEqual ociloieq +#define OCILobLoadFromFile ocilolff +#define OCILobLocatorIsInit ocilolii +#define OCILobLocatorAssign ocilolas +#define OCILogon ocilogon +#define OCILogon2 ocilgon2 +#define OCILogoff ocilgoff +#endif /* ifdef SLSHORTNAME */ + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/*-----------------------------Handle Types----------------------------------*/ + /* handle types range from 1 - 49 */ +#define OCI_HTYPE_FIRST 1 /* start value of handle type */ +#define OCI_HTYPE_ENV 1 /* environment handle */ +#define OCI_HTYPE_ERROR 2 /* error handle */ +#define OCI_HTYPE_SVCCTX 3 /* service handle */ +#define OCI_HTYPE_STMT 4 /* statement handle */ +#define OCI_HTYPE_BIND 5 /* bind handle */ +#define OCI_HTYPE_DEFINE 6 /* define handle */ +#define OCI_HTYPE_DESCRIBE 7 /* describe handle */ +#define OCI_HTYPE_SERVER 8 /* server handle */ +#define OCI_HTYPE_SESSION 9 /* authentication handle */ +#define OCI_HTYPE_AUTHINFO OCI_HTYPE_SESSION /* SessionGet auth handle */ +#define OCI_HTYPE_TRANS 10 /* transaction handle */ +#define OCI_HTYPE_COMPLEXOBJECT 11 /* complex object retrieval handle */ +#define OCI_HTYPE_SECURITY 12 /* security handle */ +#define OCI_HTYPE_SUBSCRIPTION 13 /* subscription handle */ +#define OCI_HTYPE_DIRPATH_CTX 14 /* direct path context */ +#define OCI_HTYPE_DIRPATH_COLUMN_ARRAY 15 /* direct path column array */ +#define OCI_HTYPE_DIRPATH_STREAM 16 /* direct path stream */ +#define OCI_HTYPE_PROC 17 /* process handle */ +#define OCI_HTYPE_DIRPATH_FN_CTX 18 /* direct path function context */ +#define OCI_HTYPE_DIRPATH_FN_COL_ARRAY 19 /* dp object column array */ +#define OCI_HTYPE_XADSESSION 20 /* access driver session */ +#define OCI_HTYPE_XADTABLE 21 /* access driver table */ +#define OCI_HTYPE_XADFIELD 22 /* access driver field */ +#define OCI_HTYPE_XADGRANULE 23 /* access driver granule */ +#define OCI_HTYPE_XADRECORD 24 /* access driver record */ +#define OCI_HTYPE_XADIO 25 /* access driver I/O */ +#define OCI_HTYPE_CPOOL 26 /* connection pool handle */ +#define OCI_HTYPE_SPOOL 27 /* session pool handle */ +#define OCI_HTYPE_ADMIN 28 /* admin handle */ +#define OCI_HTYPE_EVENT 29 /* HA event handle */ + +#define OCI_HTYPE_LAST 29 /* last value of a handle type */ + +/*---------------------------------------------------------------------------*/ + + +/*-------------------------Descriptor Types----------------------------------*/ + /* descriptor values range from 50 - 255 */ +#define OCI_DTYPE_FIRST 50 /* start value of descriptor type */ +#define OCI_DTYPE_LOB 50 /* lob locator */ +#define OCI_DTYPE_SNAP 51 /* snapshot descriptor */ +#define OCI_DTYPE_RSET 52 /* result set descriptor */ +#define OCI_DTYPE_PARAM 53 /* a parameter descriptor obtained from ocigparm */ +#define OCI_DTYPE_ROWID 54 /* rowid descriptor */ +#define OCI_DTYPE_COMPLEXOBJECTCOMP 55 + /* complex object retrieval descriptor */ +#define OCI_DTYPE_FILE 56 /* File Lob locator */ +#define OCI_DTYPE_AQENQ_OPTIONS 57 /* enqueue options */ +#define OCI_DTYPE_AQDEQ_OPTIONS 58 /* dequeue options */ +#define OCI_DTYPE_AQMSG_PROPERTIES 59 /* message properties */ +#define OCI_DTYPE_AQAGENT 60 /* aq agent */ +#define OCI_DTYPE_LOCATOR 61 /* LOB locator */ +#define OCI_DTYPE_INTERVAL_YM 62 /* Interval year month */ +#define OCI_DTYPE_INTERVAL_DS 63 /* Interval day second */ +#define OCI_DTYPE_AQNFY_DESCRIPTOR 64 /* AQ notify descriptor */ +#define OCI_DTYPE_DATE 65 /* Date */ +#define OCI_DTYPE_TIME 66 /* Time */ +#define OCI_DTYPE_TIME_TZ 67 /* Time with timezone */ +#define OCI_DTYPE_TIMESTAMP 68 /* Timestamp */ +#define OCI_DTYPE_TIMESTAMP_TZ 69 /* Timestamp with timezone */ +#define OCI_DTYPE_TIMESTAMP_LTZ 70 /* Timestamp with local tz */ +#define OCI_DTYPE_UCB 71 /* user callback descriptor */ +#define OCI_DTYPE_SRVDN 72 /* server DN list descriptor */ +#define OCI_DTYPE_SIGNATURE 73 /* signature */ +#define OCI_DTYPE_RESERVED_1 74 /* reserved for internal use */ +#define OCI_DTYPE_AQLIS_OPTIONS 75 /* AQ listen options */ +#define OCI_DTYPE_AQLIS_MSG_PROPERTIES 76 /* AQ listen msg props */ +#define OCI_DTYPE_CHDES 77 /* Top level change notification desc */ +#define OCI_DTYPE_TABLE_CHDES 78 /* Table change descriptor */ +#define OCI_DTYPE_ROW_CHDES 79 /* Row change descriptor */ +#define OCI_DTYPE_CQDES 80 /* Query change descriptor */ +#define OCI_DTYPE_LOB_REGION 81 /* LOB Share region descriptor */ +#define OCI_DTYPE_LAST 81 /* last value of a descriptor type */ + +/*---------------------------------------------------------------------------*/ + +/*--------------------------------LOB types ---------------------------------*/ +#define OCI_TEMP_BLOB 1 /* LOB type - BLOB ------------------ */ +#define OCI_TEMP_CLOB 2 /* LOB type - CLOB ------------------ */ +/*---------------------------------------------------------------------------*/ + +/*-------------------------Object Ptr Types----------------------------------*/ +#define OCI_OTYPE_NAME 1 /* object name */ +#define OCI_OTYPE_REF 2 /* REF to TDO */ +#define OCI_OTYPE_PTR 3 /* PTR to TDO */ +/*---------------------------------------------------------------------------*/ + +/*=============================Attribute Types===============================*/ +/* + Note: All attributes are global. New attibutes should be added to the end + of the list. Before you add an attribute see if an existing one can be + used for your handle. + + If you see any holes please use the holes first. + +*/ +/*===========================================================================*/ + + +#define OCI_ATTR_FNCODE 1 /* the OCI function code */ +#define OCI_ATTR_OBJECT 2 /* is the environment initialized in object mode */ +#define OCI_ATTR_NONBLOCKING_MODE 3 /* non blocking mode */ +#define OCI_ATTR_SQLCODE 4 /* the SQL verb */ +#define OCI_ATTR_ENV 5 /* the environment handle */ +#define OCI_ATTR_SERVER 6 /* the server handle */ +#define OCI_ATTR_SESSION 7 /* the user session handle */ +#define OCI_ATTR_TRANS 8 /* the transaction handle */ +#define OCI_ATTR_ROW_COUNT 9 /* the rows processed so far */ +#define OCI_ATTR_SQLFNCODE 10 /* the SQL verb of the statement */ +#define OCI_ATTR_PREFETCH_ROWS 11 /* sets the number of rows to prefetch */ +#define OCI_ATTR_NESTED_PREFETCH_ROWS 12 /* the prefetch rows of nested table*/ +#define OCI_ATTR_PREFETCH_MEMORY 13 /* memory limit for rows fetched */ +#define OCI_ATTR_NESTED_PREFETCH_MEMORY 14 /* memory limit for nested rows */ +#define OCI_ATTR_CHAR_COUNT 15 + /* this specifies the bind and define size in characters */ +#define OCI_ATTR_PDSCL 16 /* packed decimal scale */ +#define OCI_ATTR_FSPRECISION OCI_ATTR_PDSCL + /* fs prec for datetime data types */ +#define OCI_ATTR_PDPRC 17 /* packed decimal format */ +#define OCI_ATTR_LFPRECISION OCI_ATTR_PDPRC + /* fs prec for datetime data types */ +#define OCI_ATTR_PARAM_COUNT 18 /* number of column in the select list */ +#define OCI_ATTR_ROWID 19 /* the rowid */ +#define OCI_ATTR_CHARSET 20 /* the character set value */ +#define OCI_ATTR_NCHAR 21 /* NCHAR type */ +#define OCI_ATTR_USERNAME 22 /* username attribute */ +#define OCI_ATTR_PASSWORD 23 /* password attribute */ +#define OCI_ATTR_STMT_TYPE 24 /* statement type */ +#define OCI_ATTR_INTERNAL_NAME 25 /* user friendly global name */ +#define OCI_ATTR_EXTERNAL_NAME 26 /* the internal name for global txn */ +#define OCI_ATTR_XID 27 /* XOPEN defined global transaction id */ +#define OCI_ATTR_TRANS_LOCK 28 /* */ +#define OCI_ATTR_TRANS_NAME 29 /* string to identify a global transaction */ +#define OCI_ATTR_HEAPALLOC 30 /* memory allocated on the heap */ +#define OCI_ATTR_CHARSET_ID 31 /* Character Set ID */ +#define OCI_ATTR_CHARSET_FORM 32 /* Character Set Form */ +#define OCI_ATTR_MAXDATA_SIZE 33 /* Maximumsize of data on the server */ +#define OCI_ATTR_CACHE_OPT_SIZE 34 /* object cache optimal size */ +#define OCI_ATTR_CACHE_MAX_SIZE 35 /* object cache maximum size percentage */ +#define OCI_ATTR_PINOPTION 36 /* object cache default pin option */ +#define OCI_ATTR_ALLOC_DURATION 37 + /* object cache default allocation duration */ +#define OCI_ATTR_PIN_DURATION 38 /* object cache default pin duration */ +#define OCI_ATTR_FDO 39 /* Format Descriptor object attribute */ +#define OCI_ATTR_POSTPROCESSING_CALLBACK 40 + /* Callback to process outbind data */ +#define OCI_ATTR_POSTPROCESSING_CONTEXT 41 + /* Callback context to process outbind data */ +#define OCI_ATTR_ROWS_RETURNED 42 + /* Number of rows returned in current iter - for Bind handles */ +#define OCI_ATTR_FOCBK 43 /* Failover Callback attribute */ +#define OCI_ATTR_IN_V8_MODE 44 /* is the server/service context in V8 mode */ +#define OCI_ATTR_LOBEMPTY 45 /* empty lob ? */ +#define OCI_ATTR_SESSLANG 46 /* session language handle */ + +#define OCI_ATTR_VISIBILITY 47 /* visibility */ +#define OCI_ATTR_RELATIVE_MSGID 48 /* relative message id */ +#define OCI_ATTR_SEQUENCE_DEVIATION 49 /* sequence deviation */ + +#define OCI_ATTR_CONSUMER_NAME 50 /* consumer name */ +#define OCI_ATTR_DEQ_MODE 51 /* dequeue mode */ +#define OCI_ATTR_NAVIGATION 52 /* navigation */ +#define OCI_ATTR_WAIT 53 /* wait */ +#define OCI_ATTR_DEQ_MSGID 54 /* dequeue message id */ + +#define OCI_ATTR_PRIORITY 55 /* priority */ +#define OCI_ATTR_DELAY 56 /* delay */ +#define OCI_ATTR_EXPIRATION 57 /* expiration */ +#define OCI_ATTR_CORRELATION 58 /* correlation id */ +#define OCI_ATTR_ATTEMPTS 59 /* # of attempts */ +#define OCI_ATTR_RECIPIENT_LIST 60 /* recipient list */ +#define OCI_ATTR_EXCEPTION_QUEUE 61 /* exception queue name */ +#define OCI_ATTR_ENQ_TIME 62 /* enqueue time (only OCIAttrGet) */ +#define OCI_ATTR_MSG_STATE 63/* message state (only OCIAttrGet) */ + /* NOTE: 64-66 used below */ +#define OCI_ATTR_AGENT_NAME 64 /* agent name */ +#define OCI_ATTR_AGENT_ADDRESS 65 /* agent address */ +#define OCI_ATTR_AGENT_PROTOCOL 66 /* agent protocol */ +#define OCI_ATTR_USER_PROPERTY 67 /* user property */ +#define OCI_ATTR_SENDER_ID 68 /* sender id */ +#define OCI_ATTR_ORIGINAL_MSGID 69 /* original message id */ + +#define OCI_ATTR_QUEUE_NAME 70 /* queue name */ +#define OCI_ATTR_NFY_MSGID 71 /* message id */ +#define OCI_ATTR_MSG_PROP 72 /* message properties */ + +#define OCI_ATTR_NUM_DML_ERRORS 73 /* num of errs in array DML */ +#define OCI_ATTR_DML_ROW_OFFSET 74 /* row offset in the array */ + + /* AQ array error handling uses DML method of accessing errors */ +#define OCI_ATTR_AQ_NUM_ERRORS OCI_ATTR_NUM_DML_ERRORS +#define OCI_ATTR_AQ_ERROR_INDEX OCI_ATTR_DML_ROW_OFFSET + +#define OCI_ATTR_DATEFORMAT 75 /* default date format string */ +#define OCI_ATTR_BUF_ADDR 76 /* buffer address */ +#define OCI_ATTR_BUF_SIZE 77 /* buffer size */ + +/* For values 78 - 80, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_NUM_ROWS 81 /* number of rows in column array */ + /* NOTE that OCI_ATTR_NUM_COLS is a column + * array attribute too. + */ +#define OCI_ATTR_COL_COUNT 82 /* columns of column array + processed so far. */ +#define OCI_ATTR_STREAM_OFFSET 83 /* str off of last row processed */ +#define OCI_ATTR_SHARED_HEAPALLOC 84 /* Shared Heap Allocation Size */ + +#define OCI_ATTR_SERVER_GROUP 85 /* server group name */ + +#define OCI_ATTR_MIGSESSION 86 /* migratable session attribute */ + +#define OCI_ATTR_NOCACHE 87 /* Temporary LOBs */ + +#define OCI_ATTR_MEMPOOL_SIZE 88 /* Pool Size */ +#define OCI_ATTR_MEMPOOL_INSTNAME 89 /* Instance name */ +#define OCI_ATTR_MEMPOOL_APPNAME 90 /* Application name */ +#define OCI_ATTR_MEMPOOL_HOMENAME 91 /* Home Directory name */ +#define OCI_ATTR_MEMPOOL_MODEL 92 /* Pool Model (proc,thrd,both)*/ +#define OCI_ATTR_MODES 93 /* Modes */ + +#define OCI_ATTR_SUBSCR_NAME 94 /* name of subscription */ +#define OCI_ATTR_SUBSCR_CALLBACK 95 /* associated callback */ +#define OCI_ATTR_SUBSCR_CTX 96 /* associated callback context */ +#define OCI_ATTR_SUBSCR_PAYLOAD 97 /* associated payload */ +#define OCI_ATTR_SUBSCR_NAMESPACE 98 /* associated namespace */ + +#define OCI_ATTR_PROXY_CREDENTIALS 99 /* Proxy user credentials */ +#define OCI_ATTR_INITIAL_CLIENT_ROLES 100 /* Initial client role list */ + +#define OCI_ATTR_UNK 101 /* unknown attribute */ +#define OCI_ATTR_NUM_COLS 102 /* number of columns */ +#define OCI_ATTR_LIST_COLUMNS 103 /* parameter of the column list */ +#define OCI_ATTR_RDBA 104 /* DBA of the segment header */ +#define OCI_ATTR_CLUSTERED 105 /* whether the table is clustered */ +#define OCI_ATTR_PARTITIONED 106 /* whether the table is partitioned */ +#define OCI_ATTR_INDEX_ONLY 107 /* whether the table is index only */ +#define OCI_ATTR_LIST_ARGUMENTS 108 /* parameter of the argument list */ +#define OCI_ATTR_LIST_SUBPROGRAMS 109 /* parameter of the subprogram list */ +#define OCI_ATTR_REF_TDO 110 /* REF to the type descriptor */ +#define OCI_ATTR_LINK 111 /* the database link name */ +#define OCI_ATTR_MIN 112 /* minimum value */ +#define OCI_ATTR_MAX 113 /* maximum value */ +#define OCI_ATTR_INCR 114 /* increment value */ +#define OCI_ATTR_CACHE 115 /* number of sequence numbers cached */ +#define OCI_ATTR_ORDER 116 /* whether the sequence is ordered */ +#define OCI_ATTR_HW_MARK 117 /* high-water mark */ +#define OCI_ATTR_TYPE_SCHEMA 118 /* type's schema name */ +#define OCI_ATTR_TIMESTAMP 119 /* timestamp of the object */ +#define OCI_ATTR_NUM_ATTRS 120 /* number of sttributes */ +#define OCI_ATTR_NUM_PARAMS 121 /* number of parameters */ +#define OCI_ATTR_OBJID 122 /* object id for a table or view */ +#define OCI_ATTR_PTYPE 123 /* type of info described by */ +#define OCI_ATTR_PARAM 124 /* parameter descriptor */ +#define OCI_ATTR_OVERLOAD_ID 125 /* overload ID for funcs and procs */ +#define OCI_ATTR_TABLESPACE 126 /* table name space */ +#define OCI_ATTR_TDO 127 /* TDO of a type */ +#define OCI_ATTR_LTYPE 128 /* list type */ +#define OCI_ATTR_PARSE_ERROR_OFFSET 129 /* Parse Error offset */ +#define OCI_ATTR_IS_TEMPORARY 130 /* whether table is temporary */ +#define OCI_ATTR_IS_TYPED 131 /* whether table is typed */ +#define OCI_ATTR_DURATION 132 /* duration of temporary table */ +#define OCI_ATTR_IS_INVOKER_RIGHTS 133 /* is invoker rights */ +#define OCI_ATTR_OBJ_NAME 134 /* top level schema obj name */ +#define OCI_ATTR_OBJ_SCHEMA 135 /* schema name */ +#define OCI_ATTR_OBJ_ID 136 /* top level schema object id */ + +/* For values 137 - 141, see DirPathAPI attribute section in this file */ + + +#define OCI_ATTR_TRANS_TIMEOUT 142 /* transaction timeout */ +#define OCI_ATTR_SERVER_STATUS 143/* state of the server handle */ +#define OCI_ATTR_STATEMENT 144 /* statement txt in stmt hdl */ + +/* For value 145, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_DEQCOND 146 /* dequeue condition */ +#define OCI_ATTR_RESERVED_2 147 /* reserved */ + + +#define OCI_ATTR_SUBSCR_RECPT 148 /* recepient of subscription */ +#define OCI_ATTR_SUBSCR_RECPTPROTO 149 /* protocol for recepient */ + +/* For values 150 - 151, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_LDAP_HOST 153 /* LDAP host to connect to */ +#define OCI_ATTR_LDAP_PORT 154 /* LDAP port to connect to */ +#define OCI_ATTR_BIND_DN 155 /* bind DN */ +#define OCI_ATTR_LDAP_CRED 156 /* credentials to connect to LDAP */ +#define OCI_ATTR_WALL_LOC 157 /* client wallet location */ +#define OCI_ATTR_LDAP_AUTH 158 /* LDAP authentication method */ +#define OCI_ATTR_LDAP_CTX 159 /* LDAP adminstration context DN */ +#define OCI_ATTR_SERVER_DNS 160 /* list of registration server DNs */ + +#define OCI_ATTR_DN_COUNT 161 /* the number of server DNs */ +#define OCI_ATTR_SERVER_DN 162 /* server DN attribute */ + +#define OCI_ATTR_MAXCHAR_SIZE 163 /* max char size of data */ + +#define OCI_ATTR_CURRENT_POSITION 164 /* for scrollable result sets*/ + +/* Added to get attributes for ref cursor to statement handle */ +#define OCI_ATTR_RESERVED_3 165 /* reserved */ +#define OCI_ATTR_RESERVED_4 166 /* reserved */ + +/* For value 167, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_DIGEST_ALGO 168 /* digest algorithm */ +#define OCI_ATTR_CERTIFICATE 169 /* certificate */ +#define OCI_ATTR_SIGNATURE_ALGO 170 /* signature algorithm */ +#define OCI_ATTR_CANONICAL_ALGO 171 /* canonicalization algo. */ +#define OCI_ATTR_PRIVATE_KEY 172 /* private key */ +#define OCI_ATTR_DIGEST_VALUE 173 /* digest value */ +#define OCI_ATTR_SIGNATURE_VAL 174 /* signature value */ +#define OCI_ATTR_SIGNATURE 175 /* signature */ + +/* attributes for setting OCI stmt caching specifics in svchp */ +#define OCI_ATTR_STMTCACHESIZE 176 /* size of the stm cache */ + +/* --------------------------- Connection Pool Attributes ------------------ */ +#define OCI_ATTR_CONN_NOWAIT 178 +#define OCI_ATTR_CONN_BUSY_COUNT 179 +#define OCI_ATTR_CONN_OPEN_COUNT 180 +#define OCI_ATTR_CONN_TIMEOUT 181 +#define OCI_ATTR_STMT_STATE 182 +#define OCI_ATTR_CONN_MIN 183 +#define OCI_ATTR_CONN_MAX 184 +#define OCI_ATTR_CONN_INCR 185 + +/* For value 187, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_NUM_OPEN_STMTS 188 /* open stmts in session */ +#define OCI_ATTR_DESCRIBE_NATIVE 189 /* get native info via desc */ + +#define OCI_ATTR_BIND_COUNT 190 /* number of bind postions */ +#define OCI_ATTR_HANDLE_POSITION 191 /* pos of bind/define handle */ +#define OCI_ATTR_RESERVED_5 192 /* reserverd */ +#define OCI_ATTR_SERVER_BUSY 193 /* call in progress on server*/ + +/* For value 194, see DirPathAPI attribute section in this file */ + +/* notification presentation for recipient */ +#define OCI_ATTR_SUBSCR_RECPTPRES 195 +#define OCI_ATTR_TRANSFORMATION 196 /* AQ message transformation */ + +#define OCI_ATTR_ROWS_FETCHED 197 /* rows fetched in last call */ + +/* --------------------------- Snapshot attributes ------------------------- */ +#define OCI_ATTR_SCN_BASE 198 /* snapshot base */ +#define OCI_ATTR_SCN_WRAP 199 /* snapshot wrap */ + +/* --------------------------- Miscellanous attributes --------------------- */ +#define OCI_ATTR_RESERVED_6 200 /* reserved */ +#define OCI_ATTR_READONLY_TXN 201 /* txn is readonly */ +#define OCI_ATTR_RESERVED_7 202 /* reserved */ +#define OCI_ATTR_ERRONEOUS_COLUMN 203 /* position of erroneous col */ +#define OCI_ATTR_RESERVED_8 204 /* reserved */ +#define OCI_ATTR_ASM_VOL_SPRT 205 /* ASM volume supported? */ + +/* For value 206, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_INST_TYPE 207 /* oracle instance type */ +/******USED attribute 208 for OCI_ATTR_SPOOL_STMTCACHESIZE*******************/ + +#define OCI_ATTR_ENV_UTF16 209 /* is env in utf16 mode? */ +#define OCI_ATTR_RESERVED_9 210 /* reserved */ +#define OCI_ATTR_RESERVED_10 211 /* reserved */ + +/* For values 212 and 213, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_RESERVED_12 214 /* reserved */ +#define OCI_ATTR_RESERVED_13 215 /* reserved */ +#define OCI_ATTR_IS_EXTERNAL 216 /* whether table is external */ + + +/* -------------------------- Statement Handle Attributes ------------------ */ + +#define OCI_ATTR_RESERVED_15 217 /* reserved */ +#define OCI_ATTR_STMT_IS_RETURNING 218 /* stmt has returning clause */ +#define OCI_ATTR_RESERVED_16 219 /* reserved */ +#define OCI_ATTR_RESERVED_17 220 /* reserved */ +#define OCI_ATTR_RESERVED_18 221 /* reserved */ + +/* --------------------------- session attributes ---------------------------*/ +#define OCI_ATTR_RESERVED_19 222 /* reserved */ +#define OCI_ATTR_RESERVED_20 223 /* reserved */ +#define OCI_ATTR_CURRENT_SCHEMA 224 /* Current Schema */ +#define OCI_ATTR_RESERVED_21 415 /* reserved */ + +/* ------------------------- notification subscription ----------------------*/ +#define OCI_ATTR_SUBSCR_QOSFLAGS 225 /* QOS flags */ +#define OCI_ATTR_SUBSCR_PAYLOADCBK 226 /* Payload callback */ +#define OCI_ATTR_SUBSCR_TIMEOUT 227 /* Timeout */ +#define OCI_ATTR_SUBSCR_NAMESPACE_CTX 228 /* Namespace context */ +#define OCI_ATTR_SUBSCR_CQ_QOSFLAGS 229 + /* change notification (CQ) specific QOS flags */ +#define OCI_ATTR_SUBSCR_CQ_REGID 230 + /* change notification registration id */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_CLASS 231/* ntfn grouping class */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_VALUE 232/* ntfn grouping value */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_TYPE 233 /* ntfn grouping type */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_START_TIME 234/* ntfn grp start time */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_REPEAT_COUNT 235 /* ntfn grp rep count */ +#define OCI_ATTR_AQ_NTFN_GROUPING_MSGID_ARRAY 236 /* aq grp msgid array */ +#define OCI_ATTR_AQ_NTFN_GROUPING_COUNT 237 /* ntfns recd in grp */ + +/* ----------------------- row callback attributes ------------------------- */ +#define OCI_ATTR_BIND_ROWCBK 301 /* bind row callback */ +#define OCI_ATTR_BIND_ROWCTX 302 /* ctx for bind row callback */ +#define OCI_ATTR_SKIP_BUFFER 303 /* skip buffer in array ops */ + +/* ----------------------- XStream API attributes -------------------------- */ +#define OCI_ATTR_XSTREAM_ACK_INTERVAL 350 /* XStream ack interval */ +#define OCI_ATTR_XSTREAM_IDLE_TIMEOUT 351 /* XStream idle timeout */ + +/*----- Db Change Notification (CQ) statement handle attributes------------ */ +#define OCI_ATTR_CQ_QUERYID 304 +/* ------------- DB Change Notification reg handle attributes ---------------*/ +#define OCI_ATTR_CHNF_TABLENAMES 401 /* out: array of table names */ +#define OCI_ATTR_CHNF_ROWIDS 402 /* in: rowids needed */ +#define OCI_ATTR_CHNF_OPERATIONS 403 + /* in: notification operation filter*/ +#define OCI_ATTR_CHNF_CHANGELAG 404 + /* txn lag between notifications */ + +/* DB Change: Notification Descriptor attributes -----------------------*/ +#define OCI_ATTR_CHDES_DBNAME 405 /* source database */ +#define OCI_ATTR_CHDES_NFYTYPE 406 /* notification type flags */ +#define OCI_ATTR_CHDES_XID 407 /* XID of the transaction */ +#define OCI_ATTR_CHDES_TABLE_CHANGES 408/* array of table chg descriptors*/ + +#define OCI_ATTR_CHDES_TABLE_NAME 409 /* table name */ +#define OCI_ATTR_CHDES_TABLE_OPFLAGS 410 /* table operation flags */ +#define OCI_ATTR_CHDES_TABLE_ROW_CHANGES 411 /* array of changed rows */ +#define OCI_ATTR_CHDES_ROW_ROWID 412 /* rowid of changed row */ +#define OCI_ATTR_CHDES_ROW_OPFLAGS 413 /* row operation flags */ + +/* Statement handle attribute for db change notification */ +#define OCI_ATTR_CHNF_REGHANDLE 414 /* IN: subscription handle */ +#define OCI_ATTR_NETWORK_FILE_DESC 415 /* network file descriptor */ + +/* client name for single session proxy */ +#define OCI_ATTR_PROXY_CLIENT 416 + +/* 415 is already taken - see OCI_ATTR_RESERVED_21 */ + +/* TDE attributes on the Table */ +#define OCI_ATTR_TABLE_ENC 417/* does table have any encrypt columns */ +#define OCI_ATTR_TABLE_ENC_ALG 418 /* Table encryption Algorithm */ +#define OCI_ATTR_TABLE_ENC_ALG_ID 419 /* Internal Id of encryption Algorithm*/ + +/* -------- Attributes related to Statement cache callback ----------------- */ +#define OCI_ATTR_STMTCACHE_CBKCTX 420 /* opaque context on stmt */ +#define OCI_ATTR_STMTCACHE_CBK 421 /* callback fn for stmtcache */ + +/*---------------- Query change descriptor attributes -----------------------*/ +#define OCI_ATTR_CQDES_OPERATION 422 +#define OCI_ATTR_CQDES_TABLE_CHANGES 423 +#define OCI_ATTR_CQDES_QUERYID 424 + + +#define OCI_ATTR_CHDES_QUERIES 425 /* Top level change desc array of queries */ + +/* Please use from 143 */ + +/* -------- Internal statement attributes ------- */ +#define OCI_ATTR_RESERVED_26 422 + +/* 424 is used by OCI_ATTR_DRIVER_NAME */ +/* --------- Attributes added to support server side session pool ---------- */ +#define OCI_ATTR_CONNECTION_CLASS 425 +#define OCI_ATTR_PURITY 426 + +#define OCI_ATTR_PURITY_DEFAULT 0x00 +#define OCI_ATTR_PURITY_NEW 0x01 +#define OCI_ATTR_PURITY_SELF 0x02 + +/* -------- Attributes for Times Ten --------------------------*/ +#define OCI_ATTR_RESERVED_28 426 /* reserved */ +#define OCI_ATTR_RESERVED_29 427 /* reserved */ +#define OCI_ATTR_RESERVED_30 428 /* reserved */ +#define OCI_ATTR_RESERVED_31 429 /* reserved */ +#define OCI_ATTR_RESERVED_32 430 /* reserved */ +#define OCI_ATTR_RESERVED_41 454 /* reserved */ + + +/* ----------- Reserve internal attributes for workload replay ------------ */ +#define OCI_ATTR_RESERVED_33 433 +#define OCI_ATTR_RESERVED_34 434 + +/* statement attribute */ +#define OCI_ATTR_RESERVED_36 444 + +/* -------- Attributes for Network Session Time Out--------------------------*/ +#define OCI_ATTR_SEND_TIMEOUT 435 /* NS send timeout */ +#define OCI_ATTR_RECEIVE_TIMEOUT 436 /* NS receive timeout */ + +/*--------- Attributes related to LOB prefetch------------------------------ */ +#define OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE 438 /* default prefetch size */ +#define OCI_ATTR_LOBPREFETCH_SIZE 439 /* prefetch size */ +#define OCI_ATTR_LOBPREFETCH_LENGTH 440 /* prefetch length & chunk */ + +/*--------- Attributes related to LOB Deduplicate Regions ------------------ */ +#define OCI_ATTR_LOB_REGION_PRIMARY 442 /* Primary LOB Locator */ +#define OCI_ATTR_LOB_REGION_PRIMOFF 443 /* Offset into Primary LOB */ +#define OCI_ATTR_LOB_REGION_OFFSET 445 /* Region Offset */ +#define OCI_ATTR_LOB_REGION_LENGTH 446 /* Region Length Bytes/Chars */ +#define OCI_ATTR_LOB_REGION_MIME 447 /* Region mime type */ + +/*--------------------Attribute to fetch ROWID ------------------------------*/ +#define OCI_ATTR_FETCH_ROWID 448 + +/* server attribute */ +#define OCI_ATTR_RESERVED_37 449 + +/*------------------- Client Internal Attributes -----------------------*/ +#define OCI_ATTR_RESERVED_38 450 +#define OCI_ATTR_RESERVED_39 451 + +/* --------------- ip address attribute in environment handle -------------- */ +#define OCI_ATTR_SUBSCR_IPADDR 452 /* ip address to listen on */ + +/* server attribute */ +#define OCI_ATTR_RESERVED_40 453 + +/* DB Change: Event types ---------------*/ +#define OCI_EVENT_NONE 0x0 /* None */ +#define OCI_EVENT_STARTUP 0x1 /* Startup database */ +#define OCI_EVENT_SHUTDOWN 0x2 /* Shutdown database */ +#define OCI_EVENT_SHUTDOWN_ANY 0x3 /* Startup instance */ +#define OCI_EVENT_DROP_DB 0x4 /* Drop database */ +#define OCI_EVENT_DEREG 0x5 /* Subscription deregistered */ +#define OCI_EVENT_OBJCHANGE 0x6 /* Object change notification */ +#define OCI_EVENT_QUERYCHANGE 0x7 /* query result change */ + +/* DB Change: Operation types -----------*/ +#define OCI_OPCODE_ALLROWS 0x1 /* all rows invalidated */ +#define OCI_OPCODE_ALLOPS 0x0 /* interested in all operations */ +#define OCI_OPCODE_INSERT 0x2 /* INSERT */ +#define OCI_OPCODE_UPDATE 0x4 /* UPDATE */ +#define OCI_OPCODE_DELETE 0x8 /* DELETE */ +#define OCI_OPCODE_ALTER 0x10 /* ALTER */ +#define OCI_OPCODE_DROP 0x20 /* DROP TABLE */ +#define OCI_OPCODE_UNKNOWN 0x40 /* GENERIC/ UNKNOWN*/ + +/* -------- client side character and national character set ids ----------- */ +#define OCI_ATTR_ENV_CHARSET_ID OCI_ATTR_CHARSET_ID /* charset id in env */ +#define OCI_ATTR_ENV_NCHARSET_ID OCI_ATTR_NCHARSET_ID /* ncharset id in env */ + +/* ----------------------- ha event callback attributes -------------------- */ +#define OCI_ATTR_EVTCBK 304 /* ha callback */ +#define OCI_ATTR_EVTCTX 305 /* ctx for ha callback */ + +/* ------------------ User memory attributes (all handles) ----------------- */ +#define OCI_ATTR_USER_MEMORY 306 /* pointer to user memory */ + +/* ------- unauthorised access and user action auditing banners ------------ */ +#define OCI_ATTR_ACCESS_BANNER 307 /* access banner */ +#define OCI_ATTR_AUDIT_BANNER 308 /* audit banner */ + +/* ----------------- port no attribute in environment handle ------------- */ +#define OCI_ATTR_SUBSCR_PORTNO 390 /* port no to listen */ + +#define OCI_ATTR_RESERVED_35 437 + +/*------------- Supported Values for protocol for recepient -----------------*/ +#define OCI_SUBSCR_PROTO_OCI 0 /* oci */ +#define OCI_SUBSCR_PROTO_MAIL 1 /* mail */ +#define OCI_SUBSCR_PROTO_SERVER 2 /* server */ +#define OCI_SUBSCR_PROTO_HTTP 3 /* http */ +#define OCI_SUBSCR_PROTO_MAX 4 /* max current protocols */ + +/*------------- Supported Values for presentation for recepient -------------*/ +#define OCI_SUBSCR_PRES_DEFAULT 0 /* default */ +#define OCI_SUBSCR_PRES_XML 1 /* xml */ +#define OCI_SUBSCR_PRES_MAX 2 /* max current presentations */ + +/*------------- Supported QOS values for notification registrations ---------*/ +#define OCI_SUBSCR_QOS_RELIABLE 0x01 /* reliable */ +#define OCI_SUBSCR_QOS_PAYLOAD 0x02 /* payload delivery */ +#define OCI_SUBSCR_QOS_REPLICATE 0x04 /* replicate to director */ +#define OCI_SUBSCR_QOS_SECURE 0x08 /* secure payload delivery */ +#define OCI_SUBSCR_QOS_PURGE_ON_NTFN 0x10 /* purge on first ntfn */ +#define OCI_SUBSCR_QOS_MULTICBK 0x20 /* multi instance callback */ + /* 0x40 is used for a internal flag */ +#define OCI_SUBSCR_QOS_HAREG 0x80 /* HA reg */ + +/* ----QOS flags specific to change notification/ continuous queries CQ -----*/ +#define OCI_SUBSCR_CQ_QOS_QUERY 0x01 /* query level notification */ +#define OCI_SUBSCR_CQ_QOS_BEST_EFFORT 0x02 /* best effort notification */ +#define OCI_SUBSCR_CQ_QOS_CLQRYCACHE 0x04 /* client query caching */ + +/*------------- Supported Values for notification grouping class ------------*/ +#define OCI_SUBSCR_NTFN_GROUPING_CLASS_TIME 1 /* time */ + +/*------------- Supported Values for notification grouping type -------------*/ +#define OCI_SUBSCR_NTFN_GROUPING_TYPE_SUMMARY 1 /* summary */ +#define OCI_SUBSCR_NTFN_GROUPING_TYPE_LAST 2 /* last */ + +/* ----- Temporary attribute value for UCS2/UTF16 character set ID -------- */ +#define OCI_UCS2ID 1000 /* UCS2 charset ID */ +#define OCI_UTF16ID 1000 /* UTF16 charset ID */ + +/*============================== End OCI Attribute Types ====================*/ + +/*---------------- Server Handle Attribute Values ---------------------------*/ + +/* OCI_ATTR_SERVER_STATUS */ +#define OCI_SERVER_NOT_CONNECTED 0x0 +#define OCI_SERVER_NORMAL 0x1 + +/*---------------------------------------------------------------------------*/ + +/*------------------------- Supported Namespaces ---------------------------*/ +#define OCI_SUBSCR_NAMESPACE_ANONYMOUS 0 /* Anonymous Namespace */ +#define OCI_SUBSCR_NAMESPACE_AQ 1 /* Advanced Queues */ +#define OCI_SUBSCR_NAMESPACE_DBCHANGE 2 /* change notification */ +#define OCI_SUBSCR_NAMESPACE_MAX 3 /* Max Name Space Number */ + + +/*-------------------------Credential Types----------------------------------*/ +#define OCI_CRED_RDBMS 1 /* database username/password */ +#define OCI_CRED_EXT 2 /* externally provided credentials */ +#define OCI_CRED_PROXY 3 /* proxy authentication */ +#define OCI_CRED_RESERVED_1 4 /* reserved */ +#define OCI_CRED_RESERVED_2 5 /* reserved */ +/*---------------------------------------------------------------------------*/ + +/*------------------------Error Return Values--------------------------------*/ +#define OCI_SUCCESS 0 /* maps to SQL_SUCCESS of SAG CLI */ +#define OCI_SUCCESS_WITH_INFO 1 /* maps to SQL_SUCCESS_WITH_INFO */ +#define OCI_RESERVED_FOR_INT_USE 200 /* reserved */ +#define OCI_NO_DATA 100 /* maps to SQL_NO_DATA */ +#define OCI_ERROR -1 /* maps to SQL_ERROR */ +#define OCI_INVALID_HANDLE -2 /* maps to SQL_INVALID_HANDLE */ +#define OCI_NEED_DATA 99 /* maps to SQL_NEED_DATA */ +#define OCI_STILL_EXECUTING -3123 /* OCI would block error */ +/*---------------------------------------------------------------------------*/ + +/*--------------------- User Callback Return Values -------------------------*/ +#define OCI_CONTINUE -24200 /* Continue with the body of the OCI function */ +#define OCI_ROWCBK_DONE -24201 /* done with user row callback */ +/*---------------------------------------------------------------------------*/ + +/*------------------DateTime and Interval check Error codes------------------*/ + +/* DateTime Error Codes used by OCIDateTimeCheck() */ +#define OCI_DT_INVALID_DAY 0x1 /* Bad day */ +#define OCI_DT_DAY_BELOW_VALID 0x2 /* Bad DAy Low/high bit (1=low)*/ +#define OCI_DT_INVALID_MONTH 0x4 /* Bad MOnth */ +#define OCI_DT_MONTH_BELOW_VALID 0x8 /* Bad MOnth Low/high bit (1=low) */ +#define OCI_DT_INVALID_YEAR 0x10 /* Bad YeaR */ +#define OCI_DT_YEAR_BELOW_VALID 0x20 /* Bad YeaR Low/high bit (1=low) */ +#define OCI_DT_INVALID_HOUR 0x40 /* Bad HouR */ +#define OCI_DT_HOUR_BELOW_VALID 0x80 /* Bad HouR Low/high bit (1=low) */ +#define OCI_DT_INVALID_MINUTE 0x100 /* Bad MiNute */ +#define OCI_DT_MINUTE_BELOW_VALID 0x200 /*Bad MiNute Low/high bit (1=low) */ +#define OCI_DT_INVALID_SECOND 0x400 /* Bad SeCond */ +#define OCI_DT_SECOND_BELOW_VALID 0x800 /*bad second Low/high bit (1=low)*/ +#define OCI_DT_DAY_MISSING_FROM_1582 0x1000 + /* Day is one of those "missing" from 1582 */ +#define OCI_DT_YEAR_ZERO 0x2000 /* Year may not equal zero */ +#define OCI_DT_INVALID_TIMEZONE 0x4000 /* Bad Timezone */ +#define OCI_DT_INVALID_FORMAT 0x8000 /* Bad date format input */ + + +/* Interval Error Codes used by OCIInterCheck() */ +#define OCI_INTER_INVALID_DAY 0x1 /* Bad day */ +#define OCI_INTER_DAY_BELOW_VALID 0x2 /* Bad DAy Low/high bit (1=low) */ +#define OCI_INTER_INVALID_MONTH 0x4 /* Bad MOnth */ +#define OCI_INTER_MONTH_BELOW_VALID 0x8 /*Bad MOnth Low/high bit (1=low) */ +#define OCI_INTER_INVALID_YEAR 0x10 /* Bad YeaR */ +#define OCI_INTER_YEAR_BELOW_VALID 0x20 /*Bad YeaR Low/high bit (1=low) */ +#define OCI_INTER_INVALID_HOUR 0x40 /* Bad HouR */ +#define OCI_INTER_HOUR_BELOW_VALID 0x80 /*Bad HouR Low/high bit (1=low) */ +#define OCI_INTER_INVALID_MINUTE 0x100 /* Bad MiNute */ +#define OCI_INTER_MINUTE_BELOW_VALID 0x200 + /*Bad MiNute Low/high bit(1=low) */ +#define OCI_INTER_INVALID_SECOND 0x400 /* Bad SeCond */ +#define OCI_INTER_SECOND_BELOW_VALID 0x800 + /*bad second Low/high bit(1=low) */ +#define OCI_INTER_INVALID_FRACSEC 0x1000 /* Bad Fractional second */ +#define OCI_INTER_FRACSEC_BELOW_VALID 0x2000 + /* Bad fractional second Low/High */ + + +/*------------------------Parsing Syntax Types-------------------------------*/ +#define OCI_V7_SYNTAX 2 /* V815 language - for backwards compatibility */ +#define OCI_V8_SYNTAX 3 /* V815 language - for backwards compatibility */ +#define OCI_NTV_SYNTAX 1 /* Use what so ever is the native lang of server */ + /* these values must match the values defined in kpul.h */ +/*---------------------------------------------------------------------------*/ + +/*------------------------(Scrollable Cursor) Fetch Options------------------- + * For non-scrollable cursor, the only valid (and default) orientation is + * OCI_FETCH_NEXT + */ +#define OCI_FETCH_CURRENT 0x00000001 /* refetching current position */ +#define OCI_FETCH_NEXT 0x00000002 /* next row */ +#define OCI_FETCH_FIRST 0x00000004 /* first row of the result set */ +#define OCI_FETCH_LAST 0x00000008 /* the last row of the result set */ +#define OCI_FETCH_PRIOR 0x00000010 /* previous row relative to current */ +#define OCI_FETCH_ABSOLUTE 0x00000020 /* absolute offset from first */ +#define OCI_FETCH_RELATIVE 0x00000040 /* offset relative to current */ +#define OCI_FETCH_RESERVED_1 0x00000080 /* reserved */ +#define OCI_FETCH_RESERVED_2 0x00000100 /* reserved */ +#define OCI_FETCH_RESERVED_3 0x00000200 /* reserved */ +#define OCI_FETCH_RESERVED_4 0x00000400 /* reserved */ +#define OCI_FETCH_RESERVED_5 0x00000800 /* reserved */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------Bind and Define Options----------------------------*/ +#define OCI_SB2_IND_PTR 0x00000001 /* unused */ +#define OCI_DATA_AT_EXEC 0x00000002 /* data at execute time */ +#define OCI_DYNAMIC_FETCH 0x00000002 /* fetch dynamically */ +#define OCI_PIECEWISE 0x00000004 /* piecewise DMLs or fetch */ +#define OCI_DEFINE_RESERVED_1 0x00000008 /* reserved */ +#define OCI_BIND_RESERVED_2 0x00000010 /* reserved */ +#define OCI_DEFINE_RESERVED_2 0x00000020 /* reserved */ +#define OCI_BIND_SOFT 0x00000040 /* soft bind or define */ +#define OCI_DEFINE_SOFT 0x00000080 /* soft bind or define */ +#define OCI_BIND_RESERVED_3 0x00000100 /* reserved */ +#define OCI_IOV 0x00000200 /* For scatter gather bind/define */ +/*---------------------------------------------------------------------------*/ + +/*----------------------------- Various Modes ------------------------------*/ +#define OCI_DEFAULT 0x00000000 + /* the default value for parameters and attributes */ +/*-------------OCIInitialize Modes / OCICreateEnvironment Modes -------------*/ +#define OCI_THREADED 0x00000001 /* appl. in threaded environment */ +#define OCI_OBJECT 0x00000002 /* application in object environment */ +#define OCI_EVENTS 0x00000004 /* application is enabled for events */ +#define OCI_RESERVED1 0x00000008 /* reserved */ +#define OCI_SHARED 0x00000010 /* the application is in shared mode */ +#define OCI_RESERVED2 0x00000020 /* reserved */ +/* The following *TWO* are only valid for OCICreateEnvironment call */ +#define OCI_NO_UCB 0x00000040 /* No user callback called during ini */ +#define OCI_NO_MUTEX 0x00000080 /* the environment handle will not be */ + /* protected by a mutex internally */ +#define OCI_SHARED_EXT 0x00000100 /* Used for shared forms */ +/************************** 0x00000200 free **********************************/ +#define OCI_ALWAYS_BLOCKING 0x00000400 /* all connections always blocking */ +/************************** 0x00000800 free **********************************/ +#define OCI_USE_LDAP 0x00001000 /* allow LDAP connections */ +#define OCI_REG_LDAPONLY 0x00002000 /* only register to LDAP */ +#define OCI_UTF16 0x00004000 /* mode for all UTF16 metadata */ +#define OCI_AFC_PAD_ON 0x00008000 + /* turn on AFC blank padding when rlenp present */ +#define OCI_ENVCR_RESERVED3 0x00010000 /* reserved */ +#define OCI_NEW_LENGTH_SEMANTICS 0x00020000 /* adopt new length semantics */ + /* the new length semantics, always bytes, is used by OCIEnvNlsCreate */ +#define OCI_NO_MUTEX_STMT 0x00040000 /* Do not mutex stmt handle */ +#define OCI_MUTEX_ENV_ONLY 0x00080000 /* Mutex only the environment handle */ +#define OCI_SUPPRESS_NLS_VALIDATION 0x00100000 /* suppress nls validation */ + /* nls validation suppression is on by default; + use OCI_ENABLE_NLS_VALIDATION to disable it */ +#define OCI_MUTEX_TRY 0x00200000 /* try and acquire mutex */ +#define OCI_NCHAR_LITERAL_REPLACE_ON 0x00400000 /* nchar literal replace on */ +#define OCI_NCHAR_LITERAL_REPLACE_OFF 0x00800000 /* nchar literal replace off*/ +#define OCI_ENABLE_NLS_VALIDATION 0x01000000 /* enable nls validation */ +#define OCI_ENVCR_RESERVED4 0x02000000 /* reserved */ + +/*---------------------------------------------------------------------------*/ +/*------------------------OCIConnectionpoolCreate Modes----------------------*/ + +#define OCI_CPOOL_REINITIALIZE 0x111 + +/*---------------------------------------------------------------------------*/ +/*--------------------------------- OCILogon2 Modes -------------------------*/ + +#define OCI_LOGON2_SPOOL 0x0001 /* Use session pool */ +#define OCI_LOGON2_CPOOL OCI_CPOOL /* Use connection pool */ +#define OCI_LOGON2_STMTCACHE 0x0004 /* Use Stmt Caching */ +#define OCI_LOGON2_PROXY 0x0008 /* Proxy authentiaction */ + +/*---------------------------------------------------------------------------*/ +/*------------------------- OCISessionPoolCreate Modes ----------------------*/ + +#define OCI_SPC_REINITIALIZE 0x0001 /* Reinitialize the session pool */ +#define OCI_SPC_HOMOGENEOUS 0x0002 /* Session pool is homogeneneous */ +#define OCI_SPC_STMTCACHE 0x0004 /* Session pool has stmt cache */ +#define OCI_SPC_NO_RLB 0x0008 /* Do not enable Runtime load balancing. */ + +/*---------------------------------------------------------------------------*/ +/*--------------------------- OCISessionGet Modes ---------------------------*/ + +#define OCI_SESSGET_SPOOL 0x0001 /* SessionGet called in SPOOL mode */ +#define OCI_SESSGET_CPOOL OCI_CPOOL /* SessionGet called in CPOOL mode */ +#define OCI_SESSGET_STMTCACHE 0x0004 /* Use statement cache */ +#define OCI_SESSGET_CREDPROXY 0x0008 /* SessionGet called in proxy mode */ +#define OCI_SESSGET_CREDEXT 0x0010 +#define OCI_SESSGET_SPOOL_MATCHANY 0x0020 +#define OCI_SESSGET_PURITY_NEW 0x0040 +#define OCI_SESSGET_PURITY_SELF 0x0080 +#define OCI_SESSGET_SYSDBA 0x0100 /* SessionGet with SYSDBA privileges */ + +/*---------------------------------------------------------------------------*/ +/*------------------------ATTR Values for Session Pool-----------------------*/ +/* Attribute values for OCI_ATTR_SPOOL_GETMODE */ +#define OCI_SPOOL_ATTRVAL_WAIT 0 /* block till you get a session */ +#define OCI_SPOOL_ATTRVAL_NOWAIT 1 /* error out if no session avaliable */ +#define OCI_SPOOL_ATTRVAL_FORCEGET 2 /* get session even if max is exceeded */ + +/*---------------------------------------------------------------------------*/ +/*--------------------------- OCISessionRelease Modes -----------------------*/ + +#define OCI_SESSRLS_DROPSESS 0x0001 /* Drop the Session */ +#define OCI_SESSRLS_RETAG 0x0002 /* Retag the session */ + +/*---------------------------------------------------------------------------*/ +/*----------------------- OCISessionPoolDestroy Modes -----------------------*/ + +#define OCI_SPD_FORCE 0x0001 /* Force the sessions to terminate. + Even if there are some busy + sessions close them */ + +/*---------------------------------------------------------------------------*/ +/*----------------------------- Statement States ----------------------------*/ + +#define OCI_STMT_STATE_INITIALIZED 0x0001 +#define OCI_STMT_STATE_EXECUTED 0x0002 +#define OCI_STMT_STATE_END_OF_FETCH 0x0003 + +/*---------------------------------------------------------------------------*/ + +/*----------------------------- OCIMemStats Modes ---------------------------*/ +#define OCI_MEM_INIT 0x01 +#define OCI_MEM_CLN 0x02 +#define OCI_MEM_FLUSH 0x04 +#define OCI_DUMP_HEAP 0x80 + +#define OCI_CLIENT_STATS 0x10 +#define OCI_SERVER_STATS 0x20 + +/*----------------------------- OCIEnvInit Modes ----------------------------*/ +/* NOTE: NO NEW MODES SHOULD BE ADDED HERE BECAUSE THE RECOMMENDED METHOD + * IS TO USE THE NEW OCICreateEnvironment MODES. + */ +#define OCI_ENV_NO_UCB 0x01 /* A user callback will not be called in + OCIEnvInit() */ +#define OCI_ENV_NO_MUTEX 0x08 /* the environment handle will not be protected + by a mutex internally */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------ Prepare Modes ------------------------------------*/ +#define OCI_NO_SHARING 0x01 /* turn off statement handle sharing */ +#define OCI_PREP_RESERVED_1 0x02 /* reserved */ +#define OCI_PREP_AFC_PAD_ON 0x04 /* turn on blank padding for AFC */ +#define OCI_PREP_AFC_PAD_OFF 0x08 /* turn off blank padding for AFC */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ + +/*----------------------- Execution Modes -----------------------------------*/ +#define OCI_BATCH_MODE 0x00000001 /* batch the oci stmt for exec */ +#define OCI_EXACT_FETCH 0x00000002 /* fetch exact rows specified */ +/* #define 0x00000004 available */ +#define OCI_STMT_SCROLLABLE_READONLY \ + 0x00000008 /* if result set is scrollable */ +#define OCI_DESCRIBE_ONLY 0x00000010 /* only describe the statement */ +#define OCI_COMMIT_ON_SUCCESS 0x00000020 /* commit, if successful exec */ +#define OCI_NON_BLOCKING 0x00000040 /* non-blocking */ +#define OCI_BATCH_ERRORS 0x00000080 /* batch errors in array dmls */ +#define OCI_PARSE_ONLY 0x00000100 /* only parse the statement */ +#define OCI_EXACT_FETCH_RESERVED_1 0x00000200 /* reserved */ +#define OCI_SHOW_DML_WARNINGS 0x00000400 + /* return OCI_SUCCESS_WITH_INFO for delete/update w/no where clause */ +#define OCI_EXEC_RESERVED_2 0x00000800 /* reserved */ +#define OCI_DESC_RESERVED_1 0x00001000 /* reserved */ +#define OCI_EXEC_RESERVED_3 0x00002000 /* reserved */ +#define OCI_EXEC_RESERVED_4 0x00004000 /* reserved */ +#define OCI_EXEC_RESERVED_5 0x00008000 /* reserved */ +#define OCI_EXEC_RESERVED_6 0x00010000 /* reserved */ +#define OCI_RESULT_CACHE 0x00020000 /* hint to use query caching */ +#define OCI_NO_RESULT_CACHE 0x00040000 /*hint to bypass query caching*/ +#define OCI_EXEC_RESERVED_7 0x00080000 /* reserved */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------Authentication Modes-------------------------------*/ +#define OCI_MIGRATE 0x00000001 /* migratable auth context */ +#define OCI_SYSDBA 0x00000002 /* for SYSDBA authorization */ +#define OCI_SYSOPER 0x00000004 /* for SYSOPER authorization */ +#define OCI_PRELIM_AUTH 0x00000008 /* for preliminary authorization */ +#define OCIP_ICACHE 0x00000010 /* Private OCI cache mode */ +#define OCI_AUTH_RESERVED_1 0x00000020 /* reserved */ +#define OCI_STMT_CACHE 0x00000040 /* enable OCI Stmt Caching */ +#define OCI_STATELESS_CALL 0x00000080 /* stateless at call boundary */ +#define OCI_STATELESS_TXN 0x00000100 /* stateless at txn boundary */ +#define OCI_STATELESS_APP 0x00000200 /* stateless at user-specified pts */ +#define OCI_AUTH_RESERVED_2 0x00000400 /* reserved */ +#define OCI_AUTH_RESERVED_3 0x00000800 /* reserved */ +#define OCI_AUTH_RESERVED_4 0x00001000 /* reserved */ +#define OCI_AUTH_RESERVED_5 0x00002000 /* reserved */ +#define OCI_SYSASM 0x00008000 /* for SYSASM authorization */ +#define OCI_AUTH_RESERVED_6 0x00010000 /* reserved */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------Session End Modes----------------------------------*/ +#define OCI_SESSEND_RESERVED_1 0x0001 /* reserved */ +#define OCI_SESSEND_RESERVED_2 0x0002 /* reserved */ +/*---------------------------------------------------------------------------*/ + +/*------------------------Attach Modes---------------------------------------*/ + +/* The following attach modes are the same as the UPI modes defined in + * UPIDEF.H. Do not use these values externally. + */ + +#define OCI_FASTPATH 0x0010 /* Attach in fast path mode */ +#define OCI_ATCH_RESERVED_1 0x0020 /* reserved */ +#define OCI_ATCH_RESERVED_2 0x0080 /* reserved */ +#define OCI_ATCH_RESERVED_3 0x0100 /* reserved */ +#define OCI_CPOOL 0x0200 /* Attach using server handle from pool */ +#define OCI_ATCH_RESERVED_4 0x0400 /* reserved */ +#define OCI_ATCH_RESERVED_5 0x2000 /* reserved */ +#define OCI_ATCH_ENABLE_BEQ 0x4000 /* Allow bequeath connect strings */ +#define OCI_ATCH_RESERVED_6 0x8000 /* reserved */ +#define OCI_ATCH_RESERVED_7 0x10000 /* reserved */ +#define OCI_ATCH_RESERVED_8 0x20000 /* reserved */ + +#define OCI_SRVATCH_RESERVED5 0x01000000 /* reserved */ +#define OCI_SRVATCH_RESERVED6 0x02000000 /* reserved */ + +/*---------------------OCIStmtPrepare2 Modes---------------------------------*/ +#define OCI_PREP2_CACHE_SEARCHONLY 0x0010 /* ONly Search */ +#define OCI_PREP2_GET_PLSQL_WARNINGS 0x0020 /* Get PL/SQL warnings */ +#define OCI_PREP2_RESERVED_1 0x0040 /* reserved */ + +/*---------------------OCIStmtRelease Modes----------------------------------*/ +#define OCI_STRLS_CACHE_DELETE 0x0010 /* Delete from Cache */ + +/*---------------------OCIHanlde Mgmt Misc Modes-----------------------------*/ +#define OCI_STM_RESERVED4 0x00100000 /* reserved */ + +/*-----------------------------End Various Modes ----------------------------*/ + +/*------------------------Piece Information----------------------------------*/ +#define OCI_PARAM_IN 0x01 /* in parameter */ +#define OCI_PARAM_OUT 0x02 /* out parameter */ +/*---------------------------------------------------------------------------*/ + +/*------------------------ Transaction Start Flags --------------------------*/ +/* NOTE: OCI_TRANS_JOIN and OCI_TRANS_NOMIGRATE not supported in 8.0.X */ +#define OCI_TRANS_NEW 0x00000001 /* start a new local or global txn */ +#define OCI_TRANS_JOIN 0x00000002 /* join an existing global txn */ +#define OCI_TRANS_RESUME 0x00000004 /* resume the global txn branch */ +#define OCI_TRANS_PROMOTE 0x00000008 /* promote the local txn to global */ +#define OCI_TRANS_STARTMASK 0x000000ff /* mask for start operation flags */ + +#define OCI_TRANS_READONLY 0x00000100 /* start a readonly txn */ +#define OCI_TRANS_READWRITE 0x00000200 /* start a read-write txn */ +#define OCI_TRANS_SERIALIZABLE 0x00000400 /* start a serializable txn */ +#define OCI_TRANS_ISOLMASK 0x0000ff00 /* mask for start isolation flags */ + +#define OCI_TRANS_LOOSE 0x00010000 /* a loosely coupled branch */ +#define OCI_TRANS_TIGHT 0x00020000 /* a tightly coupled branch */ +#define OCI_TRANS_TYPEMASK 0x000f0000 /* mask for branch type flags */ + +#define OCI_TRANS_NOMIGRATE 0x00100000 /* non migratable transaction */ +#define OCI_TRANS_SEPARABLE 0x00200000 /* separable transaction (8.1.6+) */ +#define OCI_TRANS_OTSRESUME 0x00400000 /* OTS resuming a transaction */ +#define OCI_TRANS_OTHRMASK 0xfff00000 /* mask for other start flags */ + + +/*---------------------------------------------------------------------------*/ + +/*------------------------ Transaction End Flags ----------------------------*/ +#define OCI_TRANS_TWOPHASE 0x01000000 /* use two phase commit */ +#define OCI_TRANS_WRITEBATCH 0x00000001 /* force cmt-redo for local txns */ +#define OCI_TRANS_WRITEIMMED 0x00000002 /* no force cmt-redo */ +#define OCI_TRANS_WRITEWAIT 0x00000004 /* no sync cmt-redo */ +#define OCI_TRANS_WRITENOWAIT 0x00000008 /* sync cmt-redo for local txns */ +/*---------------------------------------------------------------------------*/ + +/*------------------------- AQ Constants ------------------------------------ + * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE + * The following constants must match the PL/SQL dbms_aq constants + * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE + */ +/* ------------------------- Visibility flags -------------------------------*/ +#define OCI_ENQ_IMMEDIATE 1 /* enqueue is an independent transaction */ +#define OCI_ENQ_ON_COMMIT 2 /* enqueue is part of current transaction */ + +/* ----------------------- Dequeue mode flags -------------------------------*/ +#define OCI_DEQ_BROWSE 1 /* read message without acquiring a lock */ +#define OCI_DEQ_LOCKED 2 /* read and obtain write lock on message */ +#define OCI_DEQ_REMOVE 3 /* read the message and delete it */ +#define OCI_DEQ_REMOVE_NODATA 4 /* delete message w'o returning payload */ +#define OCI_DEQ_GETSIG 5 /* get signature only */ + +/* ----------------- Dequeue navigation flags -------------------------------*/ +#define OCI_DEQ_FIRST_MSG 1 /* get first message at head of queue */ +#define OCI_DEQ_NEXT_MSG 3 /* next message that is available */ +#define OCI_DEQ_NEXT_TRANSACTION 2 /* get first message of next txn group */ +#define OCI_DEQ_FIRST_MSG_MULTI_GROUP 4 + /* start from first message and array deq across txn groups */ +#define OCI_DEQ_MULT_TRANSACTION 5 /* array dequeue across txn groups */ +#define OCI_DEQ_NEXT_MSG_MULTI_GROUP OCI_DEQ_MULT_TRANSACTION + /* array dequeue across txn groups */ + +/* ----------------- Dequeue Option Reserved flags ------------------------- */ +#define OCI_DEQ_RESERVED_1 0x000001 + +/* --------------------- Message states -------------------------------------*/ +#define OCI_MSG_WAITING 1 /* the message delay has not yet completed */ +#define OCI_MSG_READY 0 /* the message is ready to be processed */ +#define OCI_MSG_PROCESSED 2 /* the message has been processed */ +#define OCI_MSG_EXPIRED 3 /* message has moved to exception queue */ + +/* --------------------- Sequence deviation ---------------------------------*/ +#define OCI_ENQ_BEFORE 2 /* enqueue message before another message */ +#define OCI_ENQ_TOP 3 /* enqueue message before all messages */ + +/* ------------------------- Visibility flags -------------------------------*/ +#define OCI_DEQ_IMMEDIATE 1 /* dequeue is an independent transaction */ +#define OCI_DEQ_ON_COMMIT 2 /* dequeue is part of current transaction */ + +/* ------------------------ Wait --------------------------------------------*/ +#define OCI_DEQ_WAIT_FOREVER -1 /* wait forever if no message available */ +#define OCI_NTFN_GROUPING_FOREVER -1 /* send grouping notifications forever */ +#define OCI_DEQ_NO_WAIT 0 /* do not wait if no message is available */ + +#define OCI_FLOW_CONTROL_NO_TIMEOUT -1 + /* streaming enqueue: no timeout for flow control */ + +/* ------------------------ Delay -------------------------------------------*/ +#define OCI_MSG_NO_DELAY 0 /* message is available immediately */ + +/* ------------------------- Expiration -------------------------------------*/ +#define OCI_MSG_NO_EXPIRATION -1 /* message will never expire */ + +#define OCI_MSG_PERSISTENT_OR_BUFFERED 3 +#define OCI_MSG_BUFFERED 2 +#define OCI_MSG_PERSISTENT 1 + +/* ----------------------- Reserved/AQE pisdef flags ------------------------*/ +/* see aqeflg defines in kwqp.h */ +#define OCI_AQ_RESERVED_1 0x0002 +#define OCI_AQ_RESERVED_2 0x0004 +#define OCI_AQ_RESERVED_3 0x0008 +#define OCI_AQ_RESERVED_4 0x0010 + +#define OCI_AQ_STREAMING_FLAG 0x02000000 + +/* ------------------------------ Replay Info -------------------------------*/ +#define OCI_AQ_LAST_ENQUEUED 0 +#define OCI_AQ_LAST_ACKNOWLEDGED 1 + +/* -------------------------- END AQ Constants ----------------------------- */ + +/* --------------------END DateTime and Interval Constants ------------------*/ + +/*-----------------------Object Types----------------------------------------*/ +/*-----------Object Types **** Not to be Used **** --------------------------*/ +/* Deprecated */ +#define OCI_OTYPE_UNK 0 +#define OCI_OTYPE_TABLE 1 +#define OCI_OTYPE_VIEW 2 +#define OCI_OTYPE_SYN 3 +#define OCI_OTYPE_PROC 4 +#define OCI_OTYPE_FUNC 5 +#define OCI_OTYPE_PKG 6 +#define OCI_OTYPE_STMT 7 +/*---------------------------------------------------------------------------*/ + +/*=======================Describe Handle Parameter Attributes ===============*/ +/* + These attributes are orthogonal to the other set of attributes defined + above. These attrubutes are to be used only for the describe handle. +*/ +/*===========================================================================*/ +/* Attributes common to Columns and Stored Procs */ +#define OCI_ATTR_DATA_SIZE 1 /* maximum size of the data */ +#define OCI_ATTR_DATA_TYPE 2 /* the SQL type of the column/argument */ +#define OCI_ATTR_DISP_SIZE 3 /* the display size */ +#define OCI_ATTR_NAME 4 /* the name of the column/argument */ +#define OCI_ATTR_PRECISION 5 /* precision if number type */ +#define OCI_ATTR_SCALE 6 /* scale if number type */ +#define OCI_ATTR_IS_NULL 7 /* is it null ? */ +#define OCI_ATTR_TYPE_NAME 8 + /* name of the named data type or a package name for package private types */ +#define OCI_ATTR_SCHEMA_NAME 9 /* the schema name */ +#define OCI_ATTR_SUB_NAME 10 /* type name if package private type */ +#define OCI_ATTR_POSITION 11 + /* relative position of col/arg in the list of cols/args */ +/* complex object retrieval parameter attributes */ +#define OCI_ATTR_COMPLEXOBJECTCOMP_TYPE 50 +#define OCI_ATTR_COMPLEXOBJECTCOMP_TYPE_LEVEL 51 +#define OCI_ATTR_COMPLEXOBJECT_LEVEL 52 +#define OCI_ATTR_COMPLEXOBJECT_COLL_OUTOFLINE 53 + +/* Only Columns */ +#define OCI_ATTR_DISP_NAME 100 /* the display name */ +#define OCI_ATTR_ENCC_SIZE 101 /* encrypted data size */ +#define OCI_ATTR_COL_ENC 102 /* column is encrypted ? */ +#define OCI_ATTR_COL_ENC_SALT 103 /* is encrypted column salted ? */ + +/*Only Stored Procs */ +#define OCI_ATTR_OVERLOAD 210 /* is this position overloaded */ +#define OCI_ATTR_LEVEL 211 /* level for structured types */ +#define OCI_ATTR_HAS_DEFAULT 212 /* has a default value */ +#define OCI_ATTR_IOMODE 213 /* in, out inout */ +#define OCI_ATTR_RADIX 214 /* returns a radix */ +#define OCI_ATTR_NUM_ARGS 215 /* total number of arguments */ + +/* only named type attributes */ +#define OCI_ATTR_TYPECODE 216 /* object or collection */ +#define OCI_ATTR_COLLECTION_TYPECODE 217 /* varray or nested table */ +#define OCI_ATTR_VERSION 218 /* user assigned version */ +#define OCI_ATTR_IS_INCOMPLETE_TYPE 219 /* is this an incomplete type */ +#define OCI_ATTR_IS_SYSTEM_TYPE 220 /* a system type */ +#define OCI_ATTR_IS_PREDEFINED_TYPE 221 /* a predefined type */ +#define OCI_ATTR_IS_TRANSIENT_TYPE 222 /* a transient type */ +#define OCI_ATTR_IS_SYSTEM_GENERATED_TYPE 223 /* system generated type */ +#define OCI_ATTR_HAS_NESTED_TABLE 224 /* contains nested table attr */ +#define OCI_ATTR_HAS_LOB 225 /* has a lob attribute */ +#define OCI_ATTR_HAS_FILE 226 /* has a file attribute */ +#define OCI_ATTR_COLLECTION_ELEMENT 227 /* has a collection attribute */ +#define OCI_ATTR_NUM_TYPE_ATTRS 228 /* number of attribute types */ +#define OCI_ATTR_LIST_TYPE_ATTRS 229 /* list of type attributes */ +#define OCI_ATTR_NUM_TYPE_METHODS 230 /* number of type methods */ +#define OCI_ATTR_LIST_TYPE_METHODS 231 /* list of type methods */ +#define OCI_ATTR_MAP_METHOD 232 /* map method of type */ +#define OCI_ATTR_ORDER_METHOD 233 /* order method of type */ + +/* only collection element */ +#define OCI_ATTR_NUM_ELEMS 234 /* number of elements */ + +/* only type methods */ +#define OCI_ATTR_ENCAPSULATION 235 /* encapsulation level */ +#define OCI_ATTR_IS_SELFISH 236 /* method selfish */ +#define OCI_ATTR_IS_VIRTUAL 237 /* virtual */ +#define OCI_ATTR_IS_INLINE 238 /* inline */ +#define OCI_ATTR_IS_CONSTANT 239 /* constant */ +#define OCI_ATTR_HAS_RESULT 240 /* has result */ +#define OCI_ATTR_IS_CONSTRUCTOR 241 /* constructor */ +#define OCI_ATTR_IS_DESTRUCTOR 242 /* destructor */ +#define OCI_ATTR_IS_OPERATOR 243 /* operator */ +#define OCI_ATTR_IS_MAP 244 /* a map method */ +#define OCI_ATTR_IS_ORDER 245 /* order method */ +#define OCI_ATTR_IS_RNDS 246 /* read no data state method */ +#define OCI_ATTR_IS_RNPS 247 /* read no process state */ +#define OCI_ATTR_IS_WNDS 248 /* write no data state method */ +#define OCI_ATTR_IS_WNPS 249 /* write no process state */ + +#define OCI_ATTR_DESC_PUBLIC 250 /* public object */ + +/* Object Cache Enhancements : attributes for User Constructed Instances */ +#define OCI_ATTR_CACHE_CLIENT_CONTEXT 251 +#define OCI_ATTR_UCI_CONSTRUCT 252 +#define OCI_ATTR_UCI_DESTRUCT 253 +#define OCI_ATTR_UCI_COPY 254 +#define OCI_ATTR_UCI_PICKLE 255 +#define OCI_ATTR_UCI_UNPICKLE 256 +#define OCI_ATTR_UCI_REFRESH 257 + +/* for type inheritance */ +#define OCI_ATTR_IS_SUBTYPE 258 +#define OCI_ATTR_SUPERTYPE_SCHEMA_NAME 259 +#define OCI_ATTR_SUPERTYPE_NAME 260 + +/* for schemas */ +#define OCI_ATTR_LIST_OBJECTS 261 /* list of objects in schema */ + +/* for database */ +#define OCI_ATTR_NCHARSET_ID 262 /* char set id */ +#define OCI_ATTR_LIST_SCHEMAS 263 /* list of schemas */ +#define OCI_ATTR_MAX_PROC_LEN 264 /* max procedure length */ +#define OCI_ATTR_MAX_COLUMN_LEN 265 /* max column name length */ +#define OCI_ATTR_CURSOR_COMMIT_BEHAVIOR 266 /* cursor commit behavior */ +#define OCI_ATTR_MAX_CATALOG_NAMELEN 267 /* catalog namelength */ +#define OCI_ATTR_CATALOG_LOCATION 268 /* catalog location */ +#define OCI_ATTR_SAVEPOINT_SUPPORT 269 /* savepoint support */ +#define OCI_ATTR_NOWAIT_SUPPORT 270 /* nowait support */ +#define OCI_ATTR_AUTOCOMMIT_DDL 271 /* autocommit DDL */ +#define OCI_ATTR_LOCKING_MODE 272 /* locking mode */ + +/* for externally initialized context */ +#define OCI_ATTR_APPCTX_SIZE 273 /* count of context to be init*/ +#define OCI_ATTR_APPCTX_LIST 274 /* count of context to be init*/ +#define OCI_ATTR_APPCTX_NAME 275 /* name of context to be init*/ +#define OCI_ATTR_APPCTX_ATTR 276 /* attr of context to be init*/ +#define OCI_ATTR_APPCTX_VALUE 277 /* value of context to be init*/ + +/* for client id propagation */ +#define OCI_ATTR_CLIENT_IDENTIFIER 278 /* value of client id to set*/ + +/* for inheritance - part 2 */ +#define OCI_ATTR_IS_FINAL_TYPE 279 /* is final type ? */ +#define OCI_ATTR_IS_INSTANTIABLE_TYPE 280 /* is instantiable type ? */ +#define OCI_ATTR_IS_FINAL_METHOD 281 /* is final method ? */ +#define OCI_ATTR_IS_INSTANTIABLE_METHOD 282 /* is instantiable method ? */ +#define OCI_ATTR_IS_OVERRIDING_METHOD 283 /* is overriding method ? */ + +#define OCI_ATTR_DESC_SYNBASE 284 /* Describe the base object */ + + +#define OCI_ATTR_CHAR_USED 285 /* char length semantics */ +#define OCI_ATTR_CHAR_SIZE 286 /* char length */ + +/* SQLJ support */ +#define OCI_ATTR_IS_JAVA_TYPE 287 /* is java implemented type ? */ + +/* N-Tier support */ +#define OCI_ATTR_DISTINGUISHED_NAME 300 /* use DN as user name */ +#define OCI_ATTR_KERBEROS_TICKET 301 /* Kerberos ticket as cred. */ + +/* for multilanguage debugging */ +#define OCI_ATTR_ORA_DEBUG_JDWP 302 /* ORA_DEBUG_JDWP attribute */ + +#define OCI_ATTR_EDITION 288 /* ORA_EDITION */ + +#define OCI_ATTR_RESERVED_14 303 /* reserved */ + + +/*---------------------------End Describe Handle Attributes -----------------*/ + +/* For values 303 - 307, see DirPathAPI attribute section in this file */ + +/* ----------------------- Session Pool Attributes ------------------------- */ +#define OCI_ATTR_SPOOL_TIMEOUT 308 /* session timeout */ +#define OCI_ATTR_SPOOL_GETMODE 309 /* session get mode */ +#define OCI_ATTR_SPOOL_BUSY_COUNT 310 /* busy session count */ +#define OCI_ATTR_SPOOL_OPEN_COUNT 311 /* open session count */ +#define OCI_ATTR_SPOOL_MIN 312 /* min session count */ +#define OCI_ATTR_SPOOL_MAX 313 /* max session count */ +#define OCI_ATTR_SPOOL_INCR 314 /* session increment count */ +#define OCI_ATTR_SPOOL_STMTCACHESIZE 208 /*Stmt cache size of pool */ +#define OCI_ATTR_SPOOL_AUTH 460 /* Auth handle on pool handle*/ +/*------------------------------End Session Pool Attributes -----------------*/ +/*---------------------------- For XML Types ------------------------------- */ +/* For table, view and column */ +#define OCI_ATTR_IS_XMLTYPE 315 /* Is the type an XML type? */ +#define OCI_ATTR_XMLSCHEMA_NAME 316 /* Name of XML Schema */ +#define OCI_ATTR_XMLELEMENT_NAME 317 /* Name of XML Element */ +#define OCI_ATTR_XMLSQLTYPSCH_NAME 318 /* SQL type's schema for XML Ele */ +#define OCI_ATTR_XMLSQLTYPE_NAME 319 /* Name of SQL type for XML Ele */ +#define OCI_ATTR_XMLTYPE_STORED_OBJ 320 /* XML type stored as object? */ +#define OCI_ATTR_XMLTYPE_BINARY_XML 422 /* XML type stored as binary? */ + +/*---------------------------- For Subtypes ------------------------------- */ +/* For type */ +#define OCI_ATTR_HAS_SUBTYPES 321 /* Has subtypes? */ +#define OCI_ATTR_NUM_SUBTYPES 322 /* Number of subtypes */ +#define OCI_ATTR_LIST_SUBTYPES 323 /* List of subtypes */ + +/* XML flag */ +#define OCI_ATTR_XML_HRCHY_ENABLED 324 /* hierarchy enabled? */ + +/* Method flag */ +#define OCI_ATTR_IS_OVERRIDDEN_METHOD 325 /* Method is overridden? */ + +/* For values 326 - 335, see DirPathAPI attribute section in this file */ + +/*------------- Attributes for 10i Distributed Objects ----------------------*/ +#define OCI_ATTR_OBJ_SUBS 336 /* obj col/tab substitutable */ + +/* For values 337 - 338, see DirPathAPI attribute section in this file */ + +/*---------- Attributes for 10i XADFIELD (NLS language, territory -----------*/ +#define OCI_ATTR_XADFIELD_RESERVED_1 339 /* reserved */ +#define OCI_ATTR_XADFIELD_RESERVED_2 340 /* reserved */ +/*------------- Kerberos Secure Client Identifier ---------------------------*/ +#define OCI_ATTR_KERBEROS_CID 341 /* Kerberos db service ticket*/ + + +/*------------------------ Attributes for Rules objects ---------------------*/ +#define OCI_ATTR_CONDITION 342 /* rule condition */ +#define OCI_ATTR_COMMENT 343 /* comment */ +#define OCI_ATTR_VALUE 344 /* Anydata value */ +#define OCI_ATTR_EVAL_CONTEXT_OWNER 345 /* eval context owner */ +#define OCI_ATTR_EVAL_CONTEXT_NAME 346 /* eval context name */ +#define OCI_ATTR_EVALUATION_FUNCTION 347 /* eval function name */ +#define OCI_ATTR_VAR_TYPE 348 /* variable type */ +#define OCI_ATTR_VAR_VALUE_FUNCTION 349 /* variable value function */ +#define OCI_ATTR_VAR_METHOD_FUNCTION 350 /* variable method function */ +#define OCI_ATTR_ACTION_CONTEXT 351 /* action context */ +#define OCI_ATTR_LIST_TABLE_ALIASES 352 /* list of table aliases */ +#define OCI_ATTR_LIST_VARIABLE_TYPES 353 /* list of variable types */ +#define OCI_ATTR_TABLE_NAME 356 /* table name */ + +/* For values 357 - 359, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_MESSAGE_CSCN 360 /* message cscn */ +#define OCI_ATTR_MESSAGE_DSCN 361 /* message dscn */ + +/*--------------------- Audit Session ID ------------------------------------*/ +#define OCI_ATTR_AUDIT_SESSION_ID 362 /* Audit session ID */ + +/*--------------------- Kerberos TGT Keys -----------------------------------*/ +#define OCI_ATTR_KERBEROS_KEY 363 /* n-tier Kerberos cred key */ +#define OCI_ATTR_KERBEROS_CID_KEY 364 /* SCID Kerberos cred key */ + + +#define OCI_ATTR_TRANSACTION_NO 365 /* AQ enq txn number */ + +/*----------------------- Attributes for End To End Tracing -----------------*/ +#define OCI_ATTR_MODULE 366 /* module for tracing */ +#define OCI_ATTR_ACTION 367 /* action for tracing */ +#define OCI_ATTR_CLIENT_INFO 368 /* client info */ +#define OCI_ATTR_COLLECT_CALL_TIME 369 /* collect call time */ +#define OCI_ATTR_CALL_TIME 370 /* extract call time */ +#define OCI_ATTR_ECONTEXT_ID 371 /* execution-id context */ +#define OCI_ATTR_ECONTEXT_SEQ 372 /*execution-id sequence num */ + + +/*------------------------------ Session attributes -------------------------*/ +#define OCI_ATTR_SESSION_STATE 373 /* session state */ +#define OCI_SESSION_STATELESS 1 /* valid states */ +#define OCI_SESSION_STATEFUL 2 + +#define OCI_ATTR_SESSION_STATETYPE 374 /* session state type */ +#define OCI_SESSION_STATELESS_DEF 0 /* valid state types */ +#define OCI_SESSION_STATELESS_CAL 1 +#define OCI_SESSION_STATELESS_TXN 2 +#define OCI_SESSION_STATELESS_APP 3 + +#define OCI_ATTR_SESSION_STATE_CLEARED 376 /* session state cleared */ +#define OCI_ATTR_SESSION_MIGRATED 377 /* did session migrate */ +#define OCI_ATTR_SESSION_PRESERVE_STATE 388 /* preserve session state */ +#define OCI_ATTR_DRIVER_NAME 424 /* Driver Name */ + +/* -------------------------- Admin Handle Attributes ---------------------- */ + +#define OCI_ATTR_ADMIN_PFILE 389 /* client-side param file */ + +/*----------------------- Attributes for End To End Tracing -----------------*/ +/* -------------------------- HA Event Handle Attributes ------------------- */ + +#define OCI_ATTR_HOSTNAME 390 /* SYS_CONTEXT hostname */ +#define OCI_ATTR_DBNAME 391 /* SYS_CONTEXT dbname */ +#define OCI_ATTR_INSTNAME 392 /* SYS_CONTEXT instance name */ +#define OCI_ATTR_SERVICENAME 393 /* SYS_CONTEXT service name */ +#define OCI_ATTR_INSTSTARTTIME 394 /* v$instance instance start time */ +#define OCI_ATTR_HA_TIMESTAMP 395 /* event time */ +#define OCI_ATTR_RESERVED_22 396 /* reserved */ +#define OCI_ATTR_RESERVED_23 397 /* reserved */ +#define OCI_ATTR_RESERVED_24 398 /* reserved */ +#define OCI_ATTR_DBDOMAIN 399 /* db domain */ +#define OCI_ATTR_RESERVED_27 425 /* reserved */ + +#define OCI_ATTR_EVENTTYPE 400 /* event type */ +#define OCI_EVENTTYPE_HA 0 /* valid value for OCI_ATTR_EVENTTYPE */ + +#define OCI_ATTR_HA_SOURCE 401 +/* valid values for OCI_ATTR_HA_SOURCE */ +#define OCI_HA_SOURCE_INSTANCE 0 +#define OCI_HA_SOURCE_DATABASE 1 +#define OCI_HA_SOURCE_NODE 2 +#define OCI_HA_SOURCE_SERVICE 3 +#define OCI_HA_SOURCE_SERVICE_MEMBER 4 +#define OCI_HA_SOURCE_ASM_INSTANCE 5 +#define OCI_HA_SOURCE_SERVICE_PRECONNECT 6 + +#define OCI_ATTR_HA_STATUS 402 +#define OCI_HA_STATUS_DOWN 0 /* valid values for OCI_ATTR_HA_STATUS */ +#define OCI_HA_STATUS_UP 1 + +#define OCI_ATTR_HA_SRVFIRST 403 + +#define OCI_ATTR_HA_SRVNEXT 404 +/* ------------------------- Server Handle Attributes -----------------------*/ + +#define OCI_ATTR_TAF_ENABLED 405 + +/* Extra notification attributes */ +#define OCI_ATTR_NFY_FLAGS 406 + +#define OCI_ATTR_MSG_DELIVERY_MODE 407 /* msg delivery mode */ +#define OCI_ATTR_DB_CHARSET_ID 416 /* database charset ID */ +#define OCI_ATTR_DB_NCHARSET_ID 417 /* database ncharset ID */ +#define OCI_ATTR_RESERVED_25 418 /* reserved */ + +#define OCI_ATTR_FLOW_CONTROL_TIMEOUT 423 /* AQ: flow control timeout */ +/*---------------------------------------------------------------------------*/ +/* ------------------DirPathAPI attribute Section----------------------------*/ +/* All DirPathAPI attributes are in this section of the file. Existing */ +/* attributes prior to this section being created are assigned values < 2000 */ +/* Add new DirPathAPI attributes to this section and their assigned value */ +/* should be whatever the last entry is + 1. */ + +/*------------- Supported Values for Direct Path Stream Version -------------*/ +#define OCI_DIRPATH_STREAM_VERSION_1 100 +#define OCI_DIRPATH_STREAM_VERSION_2 200 +#define OCI_DIRPATH_STREAM_VERSION_3 300 /* default */ + + +#define OCI_ATTR_DIRPATH_MODE 78 /* mode of direct path operation */ +#define OCI_ATTR_DIRPATH_NOLOG 79 /* nologging option */ +#define OCI_ATTR_DIRPATH_PARALLEL 80 /* parallel (temp seg) option */ + +#define OCI_ATTR_DIRPATH_SORTED_INDEX 137 /* index that data is sorted on */ + + /* direct path index maint method (see oci8dp.h) */ +#define OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD 138 + + /* parallel load: db file, initial and next extent sizes */ + +#define OCI_ATTR_DIRPATH_FILE 139 /* DB file to load into */ +#define OCI_ATTR_DIRPATH_STORAGE_INITIAL 140 /* initial extent size */ +#define OCI_ATTR_DIRPATH_STORAGE_NEXT 141 /* next extent size */ + /* direct path index maint method (see oci8dp.h) */ +#define OCI_ATTR_DIRPATH_SKIPINDEX_METHOD 145 + + /* 8.2 dpapi support of ADTs */ +#define OCI_ATTR_DIRPATH_EXPR_TYPE 150 /* expr type of OCI_ATTR_NAME */ + +/* For the direct path API there are three data formats: + * TEXT - used mainly by SQL*Loader, data is in textual form + * STREAM - used by datapump, data is in stream loadable form + * OCI - used by OCI programs utilizing the DpApi, data is in binary form + */ +#define OCI_ATTR_DIRPATH_INPUT 151 +#define OCI_DIRPATH_INPUT_TEXT 0x01 /* text */ +#define OCI_DIRPATH_INPUT_STREAM 0x02 /* stream (datapump) */ +#define OCI_DIRPATH_INPUT_OCI 0x04 /* binary (oci) */ +#define OCI_DIRPATH_INPUT_UNKNOWN 0x08 + +#define OCI_ATTR_DIRPATH_FN_CTX 167 /* fn ctx ADT attrs or args */ + +#define OCI_ATTR_DIRPATH_OID 187 /* loading into an OID col */ +#define OCI_ATTR_DIRPATH_SID 194 /* loading into an SID col */ +#define OCI_ATTR_DIRPATH_OBJ_CONSTR 206 /* obj type of subst obj tbl */ + +/* Attr to allow setting of the stream version PRIOR to calling Prepare */ +#define OCI_ATTR_DIRPATH_STREAM_VERSION 212 /* version of the stream*/ + +#define OCIP_ATTR_DIRPATH_VARRAY_INDEX 213 /* varray index column */ + +/*------------- Supported Values for Direct Path Date cache -----------------*/ +#define OCI_ATTR_DIRPATH_DCACHE_NUM 303 /* date cache entries */ +#define OCI_ATTR_DIRPATH_DCACHE_SIZE 304 /* date cache limit */ +#define OCI_ATTR_DIRPATH_DCACHE_MISSES 305 /* date cache misses */ +#define OCI_ATTR_DIRPATH_DCACHE_HITS 306 /* date cache hits */ +#define OCI_ATTR_DIRPATH_DCACHE_DISABLE 307 /* on set: disable datecache + * on overflow. + * on get: datecache disabled? + * could be due to overflow + * or others */ + +/*------------- Attributes for 10i Updates to the DirPath API ---------------*/ +#define OCI_ATTR_DIRPATH_RESERVED_7 326 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_8 327 /* reserved */ +#define OCI_ATTR_DIRPATH_CONVERT 328 /* stream conversion needed? */ +#define OCI_ATTR_DIRPATH_BADROW 329 /* info about bad row */ +#define OCI_ATTR_DIRPATH_BADROW_LENGTH 330 /* length of bad row info */ +#define OCI_ATTR_DIRPATH_WRITE_ORDER 331 /* column fill order */ +#define OCI_ATTR_DIRPATH_GRANULE_SIZE 332 /* granule size for unload */ +#define OCI_ATTR_DIRPATH_GRANULE_OFFSET 333 /* offset to last granule */ +#define OCI_ATTR_DIRPATH_RESERVED_1 334 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_2 335 /* reserved */ + +/*------ Attributes for 10i DirPathAPI conversion (NLS lang, terr, cs) ------*/ +#define OCI_ATTR_DIRPATH_RESERVED_3 337 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_4 338 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_5 357 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_6 358 /* reserved */ + +#define OCI_ATTR_DIRPATH_LOCK_WAIT 359 /* wait for lock in dpapi */ + +#define OCI_ATTR_DIRPATH_RESERVED_9 2000 /* reserved */ + +/*------ Attribute for 10iR2 for column encryption for Direct Path API ------*/ +#define OCI_ATTR_DIRPATH_RESERVED_10 2001 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_11 2002 /* reserved */ + +/*------ Attribute to determine last column successfully converted ----------*/ +#define OCI_ATTR_CURRENT_ERRCOL 2003 /* current error column */ + + /*--Attributes for 11gR1 for multiple subtype support in Direct Path API - */ +#define OCI_ATTR_DIRPATH_SUBTYPE_INDEX 2004 /* sbtyp indx for attribute */ + +#define OCI_ATTR_DIRPATH_RESERVED_12 2005 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_13 2006 /* reserver */ + + /*--Attribute for partitioning constraint optimization in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_14 2007 /* reserved */ + + /*--Attribute for interval partitioning in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_15 2008 /* reserved */ + + /*--Attribute for interval partitioning in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_16 2009 /* reserved */ + +/*--Attribute for allowing parallel lob loads in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_17 2010 /* reserved */ + +/*--Attribute for process order number of table being loaded/unloaded */ +#define OCI_ATTR_DIRPATH_RESERVED_18 2011 /* reserved */ + +#define OCI_ATTR_DIRPATH_RESERVED_19 2012 /* reserved */ + +#define OCI_ATTR_DIRPATH_NO_INDEX_ERRORS 2013 /* reserved */ + +/*--Attribute for private sqlldr no index errors */ +#define OCI_ATTR_DIRPATH_RESERVED_20 2014 /* reserved */ + +/*--Attribute for private sqlldr partition memory limit */ +#define OCI_ATTR_DIRPATH_RESERVED_21 2015 /* reserved */ + +/* Add DirPathAPI attributes above. Next value to be assigned is 2016 */ + + +/* ------------------End of DirPathAPI attribute Section --------------------*/ +/*---------------------------------------------------------------------------*/ + + +/*---------------- Describe Handle Parameter Attribute Values ---------------*/ + +/* OCI_ATTR_CURSOR_COMMIT_BEHAVIOR */ +#define OCI_CURSOR_OPEN 0 +#define OCI_CURSOR_CLOSED 1 + +/* OCI_ATTR_CATALOG_LOCATION */ +#define OCI_CL_START 0 +#define OCI_CL_END 1 + +/* OCI_ATTR_SAVEPOINT_SUPPORT */ +#define OCI_SP_SUPPORTED 0 +#define OCI_SP_UNSUPPORTED 1 + +/* OCI_ATTR_NOWAIT_SUPPORT */ +#define OCI_NW_SUPPORTED 0 +#define OCI_NW_UNSUPPORTED 1 + +/* OCI_ATTR_AUTOCOMMIT_DDL */ +#define OCI_AC_DDL 0 +#define OCI_NO_AC_DDL 1 + +/* OCI_ATTR_LOCKING_MODE */ +#define OCI_LOCK_IMMEDIATE 0 +#define OCI_LOCK_DELAYED 1 + +/* ------------------- Instance type attribute values -----------------------*/ +#define OCI_INSTANCE_TYPE_UNKNOWN 0 +#define OCI_INSTANCE_TYPE_RDBMS 1 +#define OCI_INSTANCE_TYPE_OSM 2 + +/* ---------------- ASM Volume Device Support attribute values --------------*/ +#define OCI_ASM_VOLUME_UNSUPPORTED 0 +#define OCI_ASM_VOLUME_SUPPORTED 1 + +/*---------------------------------------------------------------------------*/ + +/*---------------------------OCIPasswordChange-------------------------------*/ +#define OCI_AUTH 0x08 /* Change the password but do not login */ + + +/*------------------------Other Constants------------------------------------*/ +#define OCI_MAX_FNS 100 /* max number of OCI Functions */ +#define OCI_SQLSTATE_SIZE 5 +#define OCI_ERROR_MAXMSG_SIZE 1024 /* max size of an error message */ +#define OCI_LOBMAXSIZE MINUB4MAXVAL /* maximum lob data size */ +#define OCI_ROWID_LEN 23 +#define OCI_LOB_CONTENTTYPE_MAXSIZE 128 /* max size of securefile contenttype */ +#define OCI_LOB_CONTENTTYPE_MAXBYTESIZE OCI_LOB_CONTENTTYPE_MAXSIZE +/*---------------------------------------------------------------------------*/ + +/*------------------------ Fail Over Events ---------------------------------*/ +#define OCI_FO_END 0x00000001 +#define OCI_FO_ABORT 0x00000002 +#define OCI_FO_REAUTH 0x00000004 +#define OCI_FO_BEGIN 0x00000008 +#define OCI_FO_ERROR 0x00000010 +/*---------------------------------------------------------------------------*/ + +/*------------------------ Fail Over Callback Return Codes ------------------*/ +#define OCI_FO_RETRY 25410 +/*---------------------------------------------------------------------------*/ + +/*------------------------- Fail Over Types ---------------------------------*/ +#define OCI_FO_NONE 0x00000001 +#define OCI_FO_SESSION 0x00000002 +#define OCI_FO_SELECT 0x00000004 +#define OCI_FO_TXNAL 0x00000008 +/*---------------------------------------------------------------------------*/ + +/*-----------------------Function Codes--------------------------------------*/ +#define OCI_FNCODE_INITIALIZE 1 /* OCIInitialize */ +#define OCI_FNCODE_HANDLEALLOC 2 /* OCIHandleAlloc */ +#define OCI_FNCODE_HANDLEFREE 3 /* OCIHandleFree */ +#define OCI_FNCODE_DESCRIPTORALLOC 4 /* OCIDescriptorAlloc */ +#define OCI_FNCODE_DESCRIPTORFREE 5 /* OCIDescriptorFree */ +#define OCI_FNCODE_ENVINIT 6 /* OCIEnvInit */ +#define OCI_FNCODE_SERVERATTACH 7 /* OCIServerAttach */ +#define OCI_FNCODE_SERVERDETACH 8 /* OCIServerDetach */ +/* unused 9 */ +#define OCI_FNCODE_SESSIONBEGIN 10 /* OCISessionBegin */ +#define OCI_FNCODE_SESSIONEND 11 /* OCISessionEnd */ +#define OCI_FNCODE_PASSWORDCHANGE 12 /* OCIPasswordChange */ +#define OCI_FNCODE_STMTPREPARE 13 /* OCIStmtPrepare */ + /* unused 14- 16 */ +#define OCI_FNCODE_BINDDYNAMIC 17 /* OCIBindDynamic */ +#define OCI_FNCODE_BINDOBJECT 18 /* OCIBindObject */ + /* 19 unused */ +#define OCI_FNCODE_BINDARRAYOFSTRUCT 20 /* OCIBindArrayOfStruct */ +#define OCI_FNCODE_STMTEXECUTE 21 /* OCIStmtExecute */ + /* unused 22-24 */ +#define OCI_FNCODE_DEFINEOBJECT 25 /* OCIDefineObject */ +#define OCI_FNCODE_DEFINEDYNAMIC 26 /* OCIDefineDynamic */ +#define OCI_FNCODE_DEFINEARRAYOFSTRUCT 27 /* OCIDefineArrayOfStruct */ +#define OCI_FNCODE_STMTFETCH 28 /* OCIStmtFetch */ +#define OCI_FNCODE_STMTGETBIND 29 /* OCIStmtGetBindInfo */ + /* 30, 31 unused */ +#define OCI_FNCODE_DESCRIBEANY 32 /* OCIDescribeAny */ +#define OCI_FNCODE_TRANSSTART 33 /* OCITransStart */ +#define OCI_FNCODE_TRANSDETACH 34 /* OCITransDetach */ +#define OCI_FNCODE_TRANSCOMMIT 35 /* OCITransCommit */ + /* 36 unused */ +#define OCI_FNCODE_ERRORGET 37 /* OCIErrorGet */ +#define OCI_FNCODE_LOBOPENFILE 38 /* OCILobFileOpen */ +#define OCI_FNCODE_LOBCLOSEFILE 39 /* OCILobFileClose */ + /* 40 was LOBCREATEFILE, unused */ + /* 41 was OCILobFileDelete, unused */ +#define OCI_FNCODE_LOBCOPY 42 /* OCILobCopy */ +#define OCI_FNCODE_LOBAPPEND 43 /* OCILobAppend */ +#define OCI_FNCODE_LOBERASE 44 /* OCILobErase */ +#define OCI_FNCODE_LOBLENGTH 45 /* OCILobGetLength */ +#define OCI_FNCODE_LOBTRIM 46 /* OCILobTrim */ +#define OCI_FNCODE_LOBREAD 47 /* OCILobRead */ +#define OCI_FNCODE_LOBWRITE 48 /* OCILobWrite */ + /* 49 unused */ +#define OCI_FNCODE_SVCCTXBREAK 50 /* OCIBreak */ +#define OCI_FNCODE_SERVERVERSION 51 /* OCIServerVersion */ + +#define OCI_FNCODE_KERBATTRSET 52 /* OCIKerbAttrSet */ + +/* unused 53 */ + +#define OCI_FNCODE_ATTRGET 54 /* OCIAttrGet */ +#define OCI_FNCODE_ATTRSET 55 /* OCIAttrSet */ +#define OCI_FNCODE_PARAMSET 56 /* OCIParamSet */ +#define OCI_FNCODE_PARAMGET 57 /* OCIParamGet */ +#define OCI_FNCODE_STMTGETPIECEINFO 58 /* OCIStmtGetPieceInfo */ +#define OCI_FNCODE_LDATOSVCCTX 59 /* OCILdaToSvcCtx */ + /* 60 unused */ +#define OCI_FNCODE_STMTSETPIECEINFO 61 /* OCIStmtSetPieceInfo */ +#define OCI_FNCODE_TRANSFORGET 62 /* OCITransForget */ +#define OCI_FNCODE_TRANSPREPARE 63 /* OCITransPrepare */ +#define OCI_FNCODE_TRANSROLLBACK 64 /* OCITransRollback */ +#define OCI_FNCODE_DEFINEBYPOS 65 /* OCIDefineByPos */ +#define OCI_FNCODE_BINDBYPOS 66 /* OCIBindByPos */ +#define OCI_FNCODE_BINDBYNAME 67 /* OCIBindByName */ +#define OCI_FNCODE_LOBASSIGN 68 /* OCILobAssign */ +#define OCI_FNCODE_LOBISEQUAL 69 /* OCILobIsEqual */ +#define OCI_FNCODE_LOBISINIT 70 /* OCILobLocatorIsInit */ + +#define OCI_FNCODE_LOBENABLEBUFFERING 71 /* OCILobEnableBuffering */ +#define OCI_FNCODE_LOBCHARSETID 72 /* OCILobCharSetID */ +#define OCI_FNCODE_LOBCHARSETFORM 73 /* OCILobCharSetForm */ +#define OCI_FNCODE_LOBFILESETNAME 74 /* OCILobFileSetName */ +#define OCI_FNCODE_LOBFILEGETNAME 75 /* OCILobFileGetName */ +#define OCI_FNCODE_LOGON 76 /* OCILogon */ +#define OCI_FNCODE_LOGOFF 77 /* OCILogoff */ +#define OCI_FNCODE_LOBDISABLEBUFFERING 78 /* OCILobDisableBuffering */ +#define OCI_FNCODE_LOBFLUSHBUFFER 79 /* OCILobFlushBuffer */ +#define OCI_FNCODE_LOBLOADFROMFILE 80 /* OCILobLoadFromFile */ + +#define OCI_FNCODE_LOBOPEN 81 /* OCILobOpen */ +#define OCI_FNCODE_LOBCLOSE 82 /* OCILobClose */ +#define OCI_FNCODE_LOBISOPEN 83 /* OCILobIsOpen */ +#define OCI_FNCODE_LOBFILEISOPEN 84 /* OCILobFileIsOpen */ +#define OCI_FNCODE_LOBFILEEXISTS 85 /* OCILobFileExists */ +#define OCI_FNCODE_LOBFILECLOSEALL 86 /* OCILobFileCloseAll */ +#define OCI_FNCODE_LOBCREATETEMP 87 /* OCILobCreateTemporary */ +#define OCI_FNCODE_LOBFREETEMP 88 /* OCILobFreeTemporary */ +#define OCI_FNCODE_LOBISTEMP 89 /* OCILobIsTemporary */ + +#define OCI_FNCODE_AQENQ 90 /* OCIAQEnq */ +#define OCI_FNCODE_AQDEQ 91 /* OCIAQDeq */ +#define OCI_FNCODE_RESET 92 /* OCIReset */ +#define OCI_FNCODE_SVCCTXTOLDA 93 /* OCISvcCtxToLda */ +#define OCI_FNCODE_LOBLOCATORASSIGN 94 /* OCILobLocatorAssign */ + +#define OCI_FNCODE_UBINDBYNAME 95 + +#define OCI_FNCODE_AQLISTEN 96 /* OCIAQListen */ + +#define OCI_FNCODE_SVC2HST 97 /* reserved */ +#define OCI_FNCODE_SVCRH 98 /* reserved */ + /* 97 and 98 are reserved for Oracle internal use */ + +#define OCI_FNCODE_TRANSMULTIPREPARE 99 /* OCITransMultiPrepare */ + +#define OCI_FNCODE_CPOOLCREATE 100 /* OCIConnectionPoolCreate */ +#define OCI_FNCODE_CPOOLDESTROY 101 /* OCIConnectionPoolDestroy */ +#define OCI_FNCODE_LOGON2 102 /* OCILogon2 */ +#define OCI_FNCODE_ROWIDTOCHAR 103 /* OCIRowidToChar */ + +#define OCI_FNCODE_SPOOLCREATE 104 /* OCISessionPoolCreate */ +#define OCI_FNCODE_SPOOLDESTROY 105 /* OCISessionPoolDestroy */ +#define OCI_FNCODE_SESSIONGET 106 /* OCISessionGet */ +#define OCI_FNCODE_SESSIONRELEASE 107 /* OCISessionRelease */ +#define OCI_FNCODE_STMTPREPARE2 108 /* OCIStmtPrepare2 */ +#define OCI_FNCODE_STMTRELEASE 109 /* OCIStmtRelease */ +#define OCI_FNCODE_AQENQARRAY 110 /* OCIAQEnqArray */ +#define OCI_FNCODE_AQDEQARRAY 111 /* OCIAQDeqArray */ +#define OCI_FNCODE_LOBCOPY2 112 /* OCILobCopy2 */ +#define OCI_FNCODE_LOBERASE2 113 /* OCILobErase2 */ +#define OCI_FNCODE_LOBLENGTH2 114 /* OCILobGetLength2 */ +#define OCI_FNCODE_LOBLOADFROMFILE2 115 /* OCILobLoadFromFile2 */ +#define OCI_FNCODE_LOBREAD2 116 /* OCILobRead2 */ +#define OCI_FNCODE_LOBTRIM2 117 /* OCILobTrim2 */ +#define OCI_FNCODE_LOBWRITE2 118 /* OCILobWrite2 */ +#define OCI_FNCODE_LOBGETSTORAGELIMIT 119 /* OCILobGetStorageLimit */ +#define OCI_FNCODE_DBSTARTUP 120 /* OCIDBStartup */ +#define OCI_FNCODE_DBSHUTDOWN 121 /* OCIDBShutdown */ +#define OCI_FNCODE_LOBARRAYREAD 122 /* OCILobArrayRead */ +#define OCI_FNCODE_LOBARRAYWRITE 123 /* OCILobArrayWrite */ +#define OCI_FNCODE_AQENQSTREAM 124 /* OCIAQEnqStreaming */ +#define OCI_FNCODE_AQGETREPLAY 125 /* OCIAQGetReplayInfo */ +#define OCI_FNCODE_AQRESETREPLAY 126 /* OCIAQResetReplayInfo */ +#define OCI_FNCODE_ARRAYDESCRIPTORALLOC 127 /*OCIArrayDescriptorAlloc */ +#define OCI_FNCODE_ARRAYDESCRIPTORFREE 128 /* OCIArrayDescriptorFree */ +#define OCI_FNCODE_LOBGETOPT 129 /* OCILobGetCptions */ +#define OCI_FNCODE_LOBSETOPT 130 /* OCILobSetCptions */ +#define OCI_FNCODE_LOBFRAGINS 131 /* OCILobFragementInsert */ +#define OCI_FNCODE_LOBFRAGDEL 132 /* OCILobFragementDelete */ +#define OCI_FNCODE_LOBFRAGMOV 133 /* OCILobFragementMove */ +#define OCI_FNCODE_LOBFRAGREP 134 /* OCILobFragementReplace */ +#define OCI_FNCODE_LOBGETDEDUPLICATEREGIONS 135/* OCILobGetDeduplicateRegions */ +#define OCI_FNCODE_APPCTXSET 136 /* OCIAppCtxSet */ +#define OCI_FNCODE_APPCTXCLEARALL 137 /* OCIAppCtxClearAll */ + +#define OCI_FNCODE_LOBGETCONTENTTYPE 138 /* OCILobGetContentType */ +#define OCI_FNCODE_LOBSETCONTENTTYPE 139 /* OCILobSetContentType */ +#define OCI_FNCODE_MAXFCN 139 /* maximum OCI function code */ + +/*---------------Statement Cache callback modes-----------------------------*/ +#define OCI_CBK_STMTCACHE_STMTPURGE 0x01 + +/*---------------------------------------------------------------------------*/ + +/*-----------------------Handle Definitions----------------------------------*/ +typedef struct OCIEnv OCIEnv; /* OCI environment handle */ +typedef struct OCIError OCIError; /* OCI error handle */ +typedef struct OCISvcCtx OCISvcCtx; /* OCI service handle */ +typedef struct OCIStmt OCIStmt; /* OCI statement handle */ +typedef struct OCIBind OCIBind; /* OCI bind handle */ +typedef struct OCIDefine OCIDefine; /* OCI Define handle */ +typedef struct OCIDescribe OCIDescribe; /* OCI Describe handle */ +typedef struct OCIServer OCIServer; /* OCI Server handle */ +typedef struct OCISession OCISession; /* OCI Authentication handle */ +typedef struct OCIComplexObject OCIComplexObject; /* OCI COR handle */ +typedef struct OCITrans OCITrans; /* OCI Transaction handle */ +typedef struct OCISecurity OCISecurity; /* OCI Security handle */ +typedef struct OCISubscription OCISubscription; /* subscription handle */ + +typedef struct OCICPool OCICPool; /* connection pool handle */ +typedef struct OCISPool OCISPool; /* session pool handle */ +typedef struct OCIAuthInfo OCIAuthInfo; /* auth handle */ +typedef struct OCIAdmin OCIAdmin; /* admin handle */ +typedef struct OCIEvent OCIEvent; /* HA event handle */ + +/*-----------------------Descriptor Definitions------------------------------*/ +typedef struct OCISnapshot OCISnapshot; /* OCI snapshot descriptor */ +typedef struct OCIResult OCIResult; /* OCI Result Set Descriptor */ +typedef struct OCILobLocator OCILobLocator; /* OCI Lob Locator descriptor */ +typedef struct OCILobRegion OCILobRegion; /* OCI Lob Regions descriptor */ +typedef struct OCIParam OCIParam; /* OCI PARameter descriptor */ +typedef struct OCIComplexObjectComp OCIComplexObjectComp; + /* OCI COR descriptor */ +typedef struct OCIRowid OCIRowid; /* OCI ROWID descriptor */ + +typedef struct OCIDateTime OCIDateTime; /* OCI DateTime descriptor */ +typedef struct OCIInterval OCIInterval; /* OCI Interval descriptor */ + +typedef struct OCIUcb OCIUcb; /* OCI User Callback descriptor */ +typedef struct OCIServerDNs OCIServerDNs; /* OCI server DN descriptor */ + +/*-------------------------- AQ Descriptors ---------------------------------*/ +typedef struct OCIAQEnqOptions OCIAQEnqOptions; /* AQ Enqueue Options hdl */ +typedef struct OCIAQDeqOptions OCIAQDeqOptions; /* AQ Dequeue Options hdl */ +typedef struct OCIAQMsgProperties OCIAQMsgProperties; /* AQ Mesg Properties */ +typedef struct OCIAQAgent OCIAQAgent; /* AQ Agent descriptor */ +typedef struct OCIAQNfyDescriptor OCIAQNfyDescriptor; /* AQ Nfy descriptor */ +typedef struct OCIAQSignature OCIAQSignature; /* AQ Siganture */ +typedef struct OCIAQListenOpts OCIAQListenOpts; /* AQ listen options */ +typedef struct OCIAQLisMsgProps OCIAQLisMsgProps; /* AQ listen msg props */ + +/*---------------------------------------------------------------------------*/ + +/* Lob typedefs for Pro*C */ +typedef struct OCILobLocator OCIClobLocator; /* OCI Character LOB Locator */ +typedef struct OCILobLocator OCIBlobLocator; /* OCI Binary LOB Locator */ +typedef struct OCILobLocator OCIBFileLocator; /* OCI Binary LOB File Locator */ +/*---------------------------------------------------------------------------*/ + +/* Undefined value for tz in interval types*/ +#define OCI_INTHR_UNK 24 + + /* These defined adjustment values */ +#define OCI_ADJUST_UNK 10 +#define OCI_ORACLE_DATE 0 +#define OCI_ANSI_DATE 1 + +/*------------------------ Lob-specific Definitions -------------------------*/ + +/* + * ociloff - OCI Lob OFFset + * + * The offset in the lob data. The offset is specified in terms of bytes for + * BLOBs and BFILes. Character offsets are used for CLOBs, NCLOBs. + * The maximum size of internal lob data is 4 gigabytes. FILE LOB + * size is limited by the operating system. + */ +typedef ub4 OCILobOffset; + +/* + * ocillen - OCI Lob LENgth (of lob data) + * + * Specifies the length of lob data in bytes for BLOBs and BFILes and in + * characters for CLOBs, NCLOBs. The maximum length of internal lob + * data is 4 gigabytes. The length of FILE LOBs is limited only by the + * operating system. + */ +typedef ub4 OCILobLength; +/* + * ocilmo - OCI Lob open MOdes + * + * The mode specifies the planned operations that will be performed on the + * FILE lob data. The FILE lob can be opened in read-only mode only. + * + * In the future, we may include read/write, append and truncate modes. Append + * is equivalent to read/write mode except that the FILE is positioned for + * writing to the end. Truncate is equivalent to read/write mode except that + * the FILE LOB data is first truncated to a length of 0 before use. + */ +enum OCILobMode +{ + OCI_LOBMODE_READONLY = 1, /* read-only */ + OCI_LOBMODE_READWRITE = 2 /* read_write for internal lobs only */ +}; +typedef enum OCILobMode OCILobMode; + +/*---------------------------------------------------------------------------*/ + + +/*----------------------------Piece Definitions------------------------------*/ + +/* if ocidef.h is being included in the app, ocidef.h should precede oci.h */ + +/* + * since clients may use oci.h, ocidef.h and ocidfn.h the following defines + * need to be guarded, usually internal clients + */ + +#ifndef OCI_FLAGS +#define OCI_FLAGS +#define OCI_ONE_PIECE 0 /* one piece */ +#define OCI_FIRST_PIECE 1 /* the first piece */ +#define OCI_NEXT_PIECE 2 /* the next of many pieces */ +#define OCI_LAST_PIECE 3 /* the last piece */ +#endif +/*---------------------------------------------------------------------------*/ + +/*--------------------------- FILE open modes -------------------------------*/ +#define OCI_FILE_READONLY 1 /* readonly mode open for FILE types */ +/*---------------------------------------------------------------------------*/ +/*--------------------------- LOB open modes --------------------------------*/ +#define OCI_LOB_READONLY 1 /* readonly mode open for ILOB types */ +#define OCI_LOB_READWRITE 2 /* read write mode open for ILOBs */ +#define OCI_LOB_WRITEONLY 3 /* Writeonly mode open for ILOB types*/ +#define OCI_LOB_APPENDONLY 4 /* Appendonly mode open for ILOB types */ +#define OCI_LOB_FULLOVERWRITE 5 /* Completely overwrite ILOB */ +#define OCI_LOB_FULLREAD 6 /* Doing a Full Read of ILOB */ + +/*----------------------- LOB Buffering Flush Flags -------------------------*/ +#define OCI_LOB_BUFFER_FREE 1 +#define OCI_LOB_BUFFER_NOFREE 2 +/*---------------------------------------------------------------------------*/ + +/*---------------------------LOB Option Types -------------------------------*/ +#define OCI_LOB_OPT_COMPRESS 1 /* SECUREFILE Compress */ +#define OCI_LOB_OPT_ENCRYPT 2 /* SECUREFILE Encrypt */ +#define OCI_LOB_OPT_DEDUPLICATE 4 /* SECUREFILE Deduplicate */ +#define OCI_LOB_OPT_ALLOCSIZE 8 /* SECUREFILE Allocation Size */ +#define OCI_LOB_OPT_CONTENTTYPE 16 /* SECUREFILE Content Type */ +#define OCI_LOB_OPT_MODTIME 32 /* SECUREFILE Modification Time */ + +/*------------------------ LOB Option Values ------------------------------*/ +/* Compression */ +#define OCI_LOB_COMPRESS_OFF 0 /* Compression off */ +#define OCI_LOB_COMPRESS_ON 1 /* Compression on */ +/* Encryption */ +#define OCI_LOB_ENCRYPT_OFF 0 /* Encryption Off */ +#define OCI_LOB_ENCRYPT_ON 2 /* Encryption On */ +/* Deduplciate */ +#define OCI_LOB_DEDUPLICATE_OFF 0 /* Deduplicate Off */ +#define OCI_LOB_DEDUPLICATE_ON 4 /* Deduplicate Lobs */ + +/*--------------------------- OCI Statement Types ---------------------------*/ + +#define OCI_STMT_UNKNOWN 0 /* Unknown statement */ +#define OCI_STMT_SELECT 1 /* select statement */ +#define OCI_STMT_UPDATE 2 /* update statement */ +#define OCI_STMT_DELETE 3 /* delete statement */ +#define OCI_STMT_INSERT 4 /* Insert Statement */ +#define OCI_STMT_CREATE 5 /* create statement */ +#define OCI_STMT_DROP 6 /* drop statement */ +#define OCI_STMT_ALTER 7 /* alter statement */ +#define OCI_STMT_BEGIN 8 /* begin ... (pl/sql statement)*/ +#define OCI_STMT_DECLARE 9 /* declare .. (pl/sql statement ) */ +#define OCI_STMT_CALL 10 /* corresponds to kpu call */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------- OCI Parameter Types ---------------------------*/ +#define OCI_PTYPE_UNK 0 /* unknown */ +#define OCI_PTYPE_TABLE 1 /* table */ +#define OCI_PTYPE_VIEW 2 /* view */ +#define OCI_PTYPE_PROC 3 /* procedure */ +#define OCI_PTYPE_FUNC 4 /* function */ +#define OCI_PTYPE_PKG 5 /* package */ +#define OCI_PTYPE_TYPE 6 /* user-defined type */ +#define OCI_PTYPE_SYN 7 /* synonym */ +#define OCI_PTYPE_SEQ 8 /* sequence */ +#define OCI_PTYPE_COL 9 /* column */ +#define OCI_PTYPE_ARG 10 /* argument */ +#define OCI_PTYPE_LIST 11 /* list */ +#define OCI_PTYPE_TYPE_ATTR 12 /* user-defined type's attribute */ +#define OCI_PTYPE_TYPE_COLL 13 /* collection type's element */ +#define OCI_PTYPE_TYPE_METHOD 14 /* user-defined type's method */ +#define OCI_PTYPE_TYPE_ARG 15 /* user-defined type method's arg */ +#define OCI_PTYPE_TYPE_RESULT 16/* user-defined type method's result */ +#define OCI_PTYPE_SCHEMA 17 /* schema */ +#define OCI_PTYPE_DATABASE 18 /* database */ +#define OCI_PTYPE_RULE 19 /* rule */ +#define OCI_PTYPE_RULE_SET 20 /* rule set */ +#define OCI_PTYPE_EVALUATION_CONTEXT 21 /* evaluation context */ +#define OCI_PTYPE_TABLE_ALIAS 22 /* table alias */ +#define OCI_PTYPE_VARIABLE_TYPE 23 /* variable type */ +#define OCI_PTYPE_NAME_VALUE 24 /* name value pair */ + +/*---------------------------------------------------------------------------*/ + +/*----------------------------- OCI List Types ------------------------------*/ +#define OCI_LTYPE_UNK 0 /* unknown */ +#define OCI_LTYPE_COLUMN 1 /* column list */ +#define OCI_LTYPE_ARG_PROC 2 /* procedure argument list */ +#define OCI_LTYPE_ARG_FUNC 3 /* function argument list */ +#define OCI_LTYPE_SUBPRG 4 /* subprogram list */ +#define OCI_LTYPE_TYPE_ATTR 5 /* type attribute */ +#define OCI_LTYPE_TYPE_METHOD 6 /* type method */ +#define OCI_LTYPE_TYPE_ARG_PROC 7 /* type method w/o result argument list */ +#define OCI_LTYPE_TYPE_ARG_FUNC 8 /* type method w/result argument list */ +#define OCI_LTYPE_SCH_OBJ 9 /* schema object list */ +#define OCI_LTYPE_DB_SCH 10 /* database schema list */ +#define OCI_LTYPE_TYPE_SUBTYPE 11 /* subtype list */ +#define OCI_LTYPE_TABLE_ALIAS 12 /* table alias list */ +#define OCI_LTYPE_VARIABLE_TYPE 13 /* variable type list */ +#define OCI_LTYPE_NAME_VALUE 14 /* name value list */ + +/*---------------------------------------------------------------------------*/ + +/*-------------------------- Memory Cartridge Services ---------------------*/ +#define OCI_MEMORY_CLEARED 1 + +/*-------------------------- Pickler Cartridge Services ---------------------*/ +typedef struct OCIPicklerTdsCtx OCIPicklerTdsCtx; +typedef struct OCIPicklerTds OCIPicklerTds; +typedef struct OCIPicklerImage OCIPicklerImage; +typedef struct OCIPicklerFdo OCIPicklerFdo; +typedef ub4 OCIPicklerTdsElement; + +typedef struct OCIAnyData OCIAnyData; + +typedef struct OCIAnyDataSet OCIAnyDataSet; +typedef struct OCIAnyDataCtx OCIAnyDataCtx; + +/*---------------------------------------------------------------------------*/ + +/*--------------------------- User Callback Constants -----------------------*/ +#define OCI_UCBTYPE_ENTRY 1 /* entry callback */ +#define OCI_UCBTYPE_EXIT 2 /* exit callback */ +#define OCI_UCBTYPE_REPLACE 3 /* replacement callback */ + +/*---------------------------------------------------------------------------*/ + +/*--------------------- NLS service type and constance ----------------------*/ +#define OCI_NLS_DAYNAME1 1 /* Native name for Monday */ +#define OCI_NLS_DAYNAME2 2 /* Native name for Tuesday */ +#define OCI_NLS_DAYNAME3 3 /* Native name for Wednesday */ +#define OCI_NLS_DAYNAME4 4 /* Native name for Thursday */ +#define OCI_NLS_DAYNAME5 5 /* Native name for Friday */ +#define OCI_NLS_DAYNAME6 6 /* Native name for for Saturday */ +#define OCI_NLS_DAYNAME7 7 /* Native name for for Sunday */ +#define OCI_NLS_ABDAYNAME1 8 /* Native abbreviated name for Monday */ +#define OCI_NLS_ABDAYNAME2 9 /* Native abbreviated name for Tuesday */ +#define OCI_NLS_ABDAYNAME3 10 /* Native abbreviated name for Wednesday */ +#define OCI_NLS_ABDAYNAME4 11 /* Native abbreviated name for Thursday */ +#define OCI_NLS_ABDAYNAME5 12 /* Native abbreviated name for Friday */ +#define OCI_NLS_ABDAYNAME6 13 /* Native abbreviated name for for Saturday */ +#define OCI_NLS_ABDAYNAME7 14 /* Native abbreviated name for for Sunday */ +#define OCI_NLS_MONTHNAME1 15 /* Native name for January */ +#define OCI_NLS_MONTHNAME2 16 /* Native name for February */ +#define OCI_NLS_MONTHNAME3 17 /* Native name for March */ +#define OCI_NLS_MONTHNAME4 18 /* Native name for April */ +#define OCI_NLS_MONTHNAME5 19 /* Native name for May */ +#define OCI_NLS_MONTHNAME6 20 /* Native name for June */ +#define OCI_NLS_MONTHNAME7 21 /* Native name for July */ +#define OCI_NLS_MONTHNAME8 22 /* Native name for August */ +#define OCI_NLS_MONTHNAME9 23 /* Native name for September */ +#define OCI_NLS_MONTHNAME10 24 /* Native name for October */ +#define OCI_NLS_MONTHNAME11 25 /* Native name for November */ +#define OCI_NLS_MONTHNAME12 26 /* Native name for December */ +#define OCI_NLS_ABMONTHNAME1 27 /* Native abbreviated name for January */ +#define OCI_NLS_ABMONTHNAME2 28 /* Native abbreviated name for February */ +#define OCI_NLS_ABMONTHNAME3 29 /* Native abbreviated name for March */ +#define OCI_NLS_ABMONTHNAME4 30 /* Native abbreviated name for April */ +#define OCI_NLS_ABMONTHNAME5 31 /* Native abbreviated name for May */ +#define OCI_NLS_ABMONTHNAME6 32 /* Native abbreviated name for June */ +#define OCI_NLS_ABMONTHNAME7 33 /* Native abbreviated name for July */ +#define OCI_NLS_ABMONTHNAME8 34 /* Native abbreviated name for August */ +#define OCI_NLS_ABMONTHNAME9 35 /* Native abbreviated name for September */ +#define OCI_NLS_ABMONTHNAME10 36 /* Native abbreviated name for October */ +#define OCI_NLS_ABMONTHNAME11 37 /* Native abbreviated name for November */ +#define OCI_NLS_ABMONTHNAME12 38 /* Native abbreviated name for December */ +#define OCI_NLS_YES 39 /* Native string for affirmative response */ +#define OCI_NLS_NO 40 /* Native negative response */ +#define OCI_NLS_AM 41 /* Native equivalent string of AM */ +#define OCI_NLS_PM 42 /* Native equivalent string of PM */ +#define OCI_NLS_AD 43 /* Native equivalent string of AD */ +#define OCI_NLS_BC 44 /* Native equivalent string of BC */ +#define OCI_NLS_DECIMAL 45 /* decimal character */ +#define OCI_NLS_GROUP 46 /* group separator */ +#define OCI_NLS_DEBIT 47 /* Native symbol of debit */ +#define OCI_NLS_CREDIT 48 /* Native sumbol of credit */ +#define OCI_NLS_DATEFORMAT 49 /* Oracle date format */ +#define OCI_NLS_INT_CURRENCY 50 /* International currency symbol */ +#define OCI_NLS_LOC_CURRENCY 51 /* Locale currency symbol */ +#define OCI_NLS_LANGUAGE 52 /* Language name */ +#define OCI_NLS_ABLANGUAGE 53 /* Abbreviation for language name */ +#define OCI_NLS_TERRITORY 54 /* Territory name */ +#define OCI_NLS_CHARACTER_SET 55 /* Character set name */ +#define OCI_NLS_LINGUISTIC_NAME 56 /* Linguistic name */ +#define OCI_NLS_CALENDAR 57 /* Calendar name */ +#define OCI_NLS_DUAL_CURRENCY 78 /* Dual currency symbol */ +#define OCI_NLS_WRITINGDIR 79 /* Language writing direction */ +#define OCI_NLS_ABTERRITORY 80 /* Territory Abbreviation */ +#define OCI_NLS_DDATEFORMAT 81 /* Oracle default date format */ +#define OCI_NLS_DTIMEFORMAT 82 /* Oracle default time format */ +#define OCI_NLS_SFDATEFORMAT 83 /* Local string formatted date format */ +#define OCI_NLS_SFTIMEFORMAT 84 /* Local string formatted time format */ +#define OCI_NLS_NUMGROUPING 85 /* Number grouping fields */ +#define OCI_NLS_LISTSEP 86 /* List separator */ +#define OCI_NLS_MONDECIMAL 87 /* Monetary decimal character */ +#define OCI_NLS_MONGROUP 88 /* Monetary group separator */ +#define OCI_NLS_MONGROUPING 89 /* Monetary grouping fields */ +#define OCI_NLS_INT_CURRENCYSEP 90 /* International currency separator */ +#define OCI_NLS_CHARSET_MAXBYTESZ 91 /* Maximum character byte size */ +#define OCI_NLS_CHARSET_FIXEDWIDTH 92 /* Fixed-width charset byte size */ +#define OCI_NLS_CHARSET_ID 93 /* Character set id */ +#define OCI_NLS_NCHARSET_ID 94 /* NCharacter set id */ + +#define OCI_NLS_MAXBUFSZ 100 /* Max buffer size may need for OCINlsGetInfo */ + +#define OCI_NLS_BINARY 0x1 /* for the binary comparison */ +#define OCI_NLS_LINGUISTIC 0x2 /* for linguistic comparison */ +#define OCI_NLS_CASE_INSENSITIVE 0x10 /* for case-insensitive comparison */ + +#define OCI_NLS_UPPERCASE 0x20 /* convert to uppercase */ +#define OCI_NLS_LOWERCASE 0x40 /* convert to lowercase */ + +#define OCI_NLS_CS_IANA_TO_ORA 0 /* Map charset name from IANA to Oracle */ +#define OCI_NLS_CS_ORA_TO_IANA 1 /* Map charset name from Oracle to IANA */ +#define OCI_NLS_LANG_ISO_TO_ORA 2 /* Map language name from ISO to Oracle */ +#define OCI_NLS_LANG_ORA_TO_ISO 3 /* Map language name from Oracle to ISO */ +#define OCI_NLS_TERR_ISO_TO_ORA 4 /* Map territory name from ISO to Oracle*/ +#define OCI_NLS_TERR_ORA_TO_ISO 5 /* Map territory name from Oracle to ISO*/ +#define OCI_NLS_TERR_ISO3_TO_ORA 6 /* Map territory name from 3-letter ISO */ + /* abbreviation to Oracle */ +#define OCI_NLS_TERR_ORA_TO_ISO3 7 /* Map territory name from Oracle to */ + /* 3-letter ISO abbreviation */ +#define OCI_NLS_LOCALE_A2_ISO_TO_ORA 8 + /*Map locale name from A2 ISO to oracle*/ +#define OCI_NLS_LOCALE_A2_ORA_TO_ISO 9 + /*Map locale name from oracle to A2 ISO*/ + +typedef struct OCIMsg OCIMsg; +typedef ub4 OCIWchar; + +#define OCI_XMLTYPE_CREATE_OCISTRING 1 +#define OCI_XMLTYPE_CREATE_CLOB 2 +#define OCI_XMLTYPE_CREATE_BLOB 3 + +/*------------------------- Kerber Authentication Modes ---------------------*/ +#define OCI_KERBCRED_PROXY 1 /* Apply Kerberos Creds for Proxy */ +#define OCI_KERBCRED_CLIENT_IDENTIFIER 2/*Apply Creds for Secure Client ID */ + +/*------------------------- Database Startup Flags --------------------------*/ +#define OCI_DBSTARTUPFLAG_FORCE 0x00000001 /* Abort running instance, start */ +#define OCI_DBSTARTUPFLAG_RESTRICT 0x00000002 /* Restrict access to DBA */ + +/*------------------------- Database Shutdown Modes -------------------------*/ +#define OCI_DBSHUTDOWN_TRANSACTIONAL 1 /* Wait for all the transactions */ +#define OCI_DBSHUTDOWN_TRANSACTIONAL_LOCAL 2 /* Wait for local transactions */ +#define OCI_DBSHUTDOWN_IMMEDIATE 3 /* Terminate and roll back */ +#define OCI_DBSHUTDOWN_ABORT 4 /* Terminate and don't roll back */ +#define OCI_DBSHUTDOWN_FINAL 5 /* Orderly shutdown */ + +/*------------------------- Version information -----------------------------*/ +#define OCI_MAJOR_VERSION 11 /* Major release version */ +#define OCI_MINOR_VERSION 2 /* Minor release version */ + +/*---------------------- OCIIOV structure definitions -----------------------*/ +struct OCIIOV +{ + void *bfp; /* The Pointer to the data buffer */ + ub4 bfl; /* Length of the Data Buffer */ +}; +typedef struct OCIIOV OCIIOV; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* None */ + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + +/* see ociap.h or ocikp.h */ + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + +/* None */ + + +#endif /* OCI_ORACLE */ + + +/* more includes */ + +#ifndef OCI1_ORACLE +#include +#endif + +#ifndef ORO_ORACLE +#include +#endif + +#ifndef ORI_ORACLE +#include +#endif + +#ifndef ORL_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#include +#endif + +#ifndef OCIEXTP_ORACLE +#include +#endif + +#include +#include + +#ifndef OCIXMLDB_ORACLE +#include +#endif + +#ifndef OCI8DP_ORACLE +#include /* interface definitions for the direct path api */ +#endif + +#ifndef OCIEXTP_ORACLE +#include +#endif + +#ifndef OCIXSTREAM_ORACLE +#include +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + diff --git a/OCI/include/oci1.h b/OCI/include/oci1.h new file mode 100644 index 0000000..8c59c94 --- /dev/null +++ b/OCI/include/oci1.h @@ -0,0 +1,182 @@ + +/* Copyright (c) 1997, 2005, Oracle. All rights reserved. */ + +/* NOTE: See 'header_template.doc' in the 'doc' dve under the 'forms' + directory for the header file template that includes instructions. +*/ + +/* + NAME + oci1.h - Cartridge Service definitions + + DESCRIPTION + + + RELATED DOCUMENTS + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + + + PRIVATE FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + nramakri 01/16/98 - remove #ifdef NEVER clause + ewaugh 12/18/97 - Turn type wrappers into functions. + skabraha 12/02/97 - Adding data structures & constants for OCIFile + rhwu 12/02/97 - OCI Thread + nramakri 12/15/97 - move to core4 + ewaugh 12/11/97 - add OCIFormat package constants + ssamu 12/10/97 - do not include s.h + nramakri 11/19/97 - add OCIExtract definitions + ssamu 11/14/97 - creation + +*/ + + +#ifndef OCI1_ORACLE +# define OCI1_ORACLE + +# ifndef ORATYPES +# include +# endif + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* Constants required by the OCIFormat package. */ + +#define OCIFormatUb1(variable) OCIFormatTUb1(), &(variable) +#define OCIFormatUb2(variable) OCIFormatTUb2(), &(variable) +#define OCIFormatUb4(variable) OCIFormatTUb4(), &(variable) +#define OCIFormatUword(variable) OCIFormatTUword(), &(variable) +#define OCIFormatUbig_ora(variable) OCIFormatTUbig_ora(), &(variable) +#define OCIFormatSb1(variable) OCIFormatTSb1(), &(variable) +#define OCIFormatSb2(variable) OCIFormatTSb2(), &(variable) +#define OCIFormatSb4(variable) OCIFormatTSb4(), &(variable) +#define OCIFormatSword(variable) OCIFormatTSword(), &(variable) +#define OCIFormatSbig_ora(variable) OCIFormatTSbig_ora(), &(variable) +#define OCIFormatEb1(variable) OCIFormatTEb1(), &(variable) +#define OCIFormatEb2(variable) OCIFormatTEb2(), &(variable) +#define OCIFormatEb4(variable) OCIFormatTEb4(), &(variable) +#define OCIFormatEword(variable) OCIFormatTEword(), &(variable) +#define OCIFormatChar(variable) OCIFormatTChar(), &(variable) +#define OCIFormatText(variable) OCIFormatTText(), (variable) +#define OCIFormatDouble(variable) OCIFormatTDouble(), &(variable) +#define OCIFormatDvoid(variable) OCIFormatTDvoid(), (variable) +#define OCIFormatEnd OCIFormatTEnd() + +#define OCIFormatDP 6 + + +/*----------------- Public Constants for OCIFile -------------------------*/ + +/* flags for open.*/ +/* flags for mode */ +#define OCI_FILE_READ_ONLY 1 /* open for read only */ +#define OCI_FILE_WRITE_ONLY 2 /* open for write only */ +#define OCI_FILE_READ_WRITE 3 /* open for read & write */ +/* flags for create */ +#define OCI_FILE_EXIST 0 /* the file should exist */ +#define OCI_FILE_CREATE 1 /* create if the file doesn't exist */ +#define OCI_FILE_EXCL 2 /* the file should not exist */ +#define OCI_FILE_TRUNCATE 4 /* create if the file doesn't exist, + else truncate file the file to 0 */ +#define OCI_FILE_APPEND 8 /* open the file in append mode */ + +/* flags for seek */ +#define OCI_FILE_SEEK_BEGINNING 1 /* seek from the beginning of the file */ +#define OCI_FILE_SEEK_CURRENT 2 /* seek from the current position */ +#define OCI_FILE_SEEK_END 3 /* seek from the end of the file */ + +#define OCI_FILE_FORWARD 1 /* seek forward */ +#define OCI_FILE_BACKWARD 2 /* seek backward */ + +/* file type */ +#define OCI_FILE_BIN 0 /* binary file */ +#define OCI_FILE_TEXT 1 /* text file */ +#define OCI_FILE_STDIN 2 /* standard i/p */ +#define OCI_FILE_STDOUT 3 /* standard o/p */ +#define OCI_FILE_STDERR 4 /* standard error */ + +/* Represents an open file */ +typedef struct OCIFileObject OCIFileObject; + + +/*--------------------- OCI Thread Object Definitions------------------------*/ + +/* OCIThread Context */ +typedef struct OCIThreadContext OCIThreadContext; + +/* OCIThread Mutual Exclusion Lock */ +typedef struct OCIThreadMutex OCIThreadMutex; + +/* OCIThread Key for Thread-Specific Data */ +typedef struct OCIThreadKey OCIThreadKey; + +/* OCIThread Thread ID */ +typedef struct OCIThreadId OCIThreadId; + +/* OCIThread Thread Handle */ +typedef struct OCIThreadHandle OCIThreadHandle; + + +/*-------------------- OCI Thread Callback Function Pointers ----------------*/ + +/* OCIThread Key Destructor Function Type */ +typedef void (*OCIThreadKeyDestFunc)( void * ); + + +/* Flags passed into OCIExtractFromXXX routines to direct processing */ +#define OCI_EXTRACT_CASE_SENSITIVE 0x1 /* matching is case sensitive */ +#define OCI_EXTRACT_UNIQUE_ABBREVS 0x2 /* unique abbreviations for keys + are allowed */ +#define OCI_EXTRACT_APPEND_VALUES 0x4 /* if multiple values for a key + exist, this determines if the + new value should be appended + to (or replace) the current + list of values */ + +/* Constants passed into OCIExtractSetKey routine */ +#define OCI_EXTRACT_MULTIPLE 0x8 /* key can accept multiple values */ +#define OCI_EXTRACT_TYPE_BOOLEAN 1 /* key type is boolean */ +#define OCI_EXTRACT_TYPE_STRING 2 /* key type is string */ +#define OCI_EXTRACT_TYPE_INTEGER 3 /* key type is integer */ +#define OCI_EXTRACT_TYPE_OCINUM 4 /* key type is ocinum */ + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCI1_ORACLE */ diff --git a/OCI/include/oci8dp.h b/OCI/include/oci8dp.h new file mode 100644 index 0000000..d73258c --- /dev/null +++ b/OCI/include/oci8dp.h @@ -0,0 +1,317 @@ +/* + * + */ + +/* Copyright (c) 1998, 2005, Oracle. All rights reserved. */ + +/* + NAME + oci8dp.h - OCI: Direct Path API interface prototypes. + + DESCRIPTION + Public types, constants, and interfaces to the direct path API. + + RELATED DOCUMENTS + + NOTES + This file is not directly included by the application, this file + is included by "oci.h", which the application should include. + + MODIFIED (MM/DD/YY) + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + rphillip 02/27/04 - Add OCI_DIRPATH_COL_ERROR + srseshad 03/12/03 - convert oci public api to ansi + msakayed 10/28/02 - Bug #2643907: add OCI_ATTR_DIRPATH_SKIPINDEX_METHOD + cmlim 04/13/01 - remove OCIDirPathStreamToStream - not used by dpapi + cmlim 04/02/01 - OCI_DIRPATH_EXPR_OPQ_SQL_FN to OCI_DIRPATH_EXPR_SQL + ebatbout 01/22/01 - PARTIAL value for OCIDirPathDataSave action parameter + cmlim 07/20/00 - support opaques/sql strings in 8.2 dpapi + cmlim 08/14/00 - support refs in 8.2 dpapi + cmlim 04/17/00 - add defines for OCIDirPathFuncCtx handle & OCI_ATTR_D + whe 09/01/99 - 976457:check __cplusplus for C++ code + abrumm 04/16/99 - dpapi: more attributes + abrumm 02/26/99 - add defines for DataSave action + abrumm 10/04/98 - clen must be a ub4 + abrumm 05/27/98 - add column array flag values + abrumm 05/12/98 - direct path api support + abrumm 03/31/98 - OCI direct path interface support + abrumm 03/18/98 - Creation + +*/ + +#ifndef OCI8DP_ORACLE +# define OCI8DP_ORACLE + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN +#include +#endif + +#ifndef OCI_ORACLE +#include +#endif + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/*----- Handles and descriptors for direct path operations (OCIDirPath*) ----*/ + +typedef struct OCIDirPathCtx OCIDirPathCtx; /* context */ +typedef struct OCIDirPathFuncCtx OCIDirPathFuncCtx; /* function context */ +typedef struct OCIDirPathColArray OCIDirPathColArray; /* column array */ +typedef struct OCIDirPathStream OCIDirPathStream; /* stream */ +typedef struct OCIDirPathDesc OCIDirPathDesc; /* direct path descriptor */ + + /*----- Defines for Direct Path Options -----*/ + + /* values for OCI_ATTR_DIRPATH_MODE attribute */ +#define OCI_DIRPATH_LOAD 1 /* direct path load operation */ +#define OCI_DIRPATH_UNLOAD 2 /* direct path unload operation */ +#define OCI_DIRPATH_CONVERT 3 /* direct path convert only operation */ + + /*----- values for OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD attribute -----*/ +#define OCI_DIRPATH_INDEX_MAINT_SINGLE_ROW 1 + +/* Note that there are two attributes dealing with index maintenance - + * OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD and OCI_ATTR_DIRPATH_SKIPINDEX_METHOD. + * OCI_ATTR_DIRPATH_SKIPINDEX_METHOD exists to isolate the behavior for + * skipping index maintenance since maintenance of unusable indexes is + * orthogonal to that of single row insertion. + * For backwards compatibility we still allow users to specify skip + * methods in OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD so make sure the + * enumerations for the two attributes are distinct. + */ + /*----- values for OCI_ATTR_DIRPATH_SKIPINDEX_METHOD attribute -----*/ +#define OCI_DIRPATH_INDEX_MAINT_SKIP_UNUSABLE 2 +#define OCI_DIRPATH_INDEX_MAINT_DONT_SKIP_UNUSABLE 3 +#define OCI_DIRPATH_INDEX_MAINT_SKIP_ALL 4 + + /* values for OCI_ATTR_STATE attribute of OCIDirPathCtx */ +#define OCI_DIRPATH_NORMAL 1 /* can accept rows, last row complete */ +#define OCI_DIRPATH_PARTIAL 2 /* last row was partial */ +#define OCI_DIRPATH_NOT_PREPARED 3 /* direct path context is not prepared */ + + /*----- values for cflg argument to OCIDirpathColArrayEntrySet -----*/ +#define OCI_DIRPATH_COL_COMPLETE 0 /* column data is complete */ +#define OCI_DIRPATH_COL_NULL 1 /* column is null */ +#define OCI_DIRPATH_COL_PARTIAL 2 /* column data is partial */ +#define OCI_DIRPATH_COL_ERROR 3 /* column error, ignore row */ + /*----- values for action parameter to OCIDirPathDataSave -----*/ +#define OCI_DIRPATH_DATASAVE_SAVEONLY 0 /* data save point only */ +#define OCI_DIRPATH_DATASAVE_FINISH 1 /* execute finishing logic */ +/* save portion of input data (before space error occurred) and finish */ +#define OCI_DIRPATH_DATASAVE_PARTIAL 2 + + /*- OCI_ATTR_DIRPATH_EXPR_TYPE values (describes OCI_ATTR_NAME expr type) -*/ +#define OCI_DIRPATH_EXPR_OBJ_CONSTR 1 /* NAME is an object constructor */ +#define OCI_DIRPATH_EXPR_SQL 2 /* NAME is an opaque or sql function */ +#define OCI_DIRPATH_EXPR_REF_TBLNAME 3 /* NAME is table name if ref is scoped*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------------ OCIDirPathCtx Operations -------------------------*/ + +/* + NAME + OCIDirPathAbort - OCI: Abort a direct path operation. + + DESCRIPTION + Aborts a direct path operation. Upon successful completion + the direct path context is no longer valid. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathAbort( OCIDirPathCtx *dpctx, OCIError *errhp ); + +/* + NAME + OCIDirPathDataSave - OCI: Execute a data save point. + + DESCRIPTION + Successful return of this function indicates that a data save + point has been executed. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathDataSave( OCIDirPathCtx *dpctx, OCIError *errhp, ub4 action ); + +/* + NAME + OCIDirPathFinish - OCI: Finish a direct path operation. + + DESCRIPTION + Finishes a direct path operation. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathFinish( OCIDirPathCtx *dpctx, OCIError *errhp ); + +/* + NAME + OCIDirPathFlushRow - OCI: Flush a partial row from the server. + + DESCRIPTION + Flushes a partially loaded row from the server. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathFlushRow( OCIDirPathCtx *dpctx, OCIError *errhp ); + +/* + NAME + OCIDirPathPrepare - OCI: Prepare a direct path operation. + + DESCRIPTION + Prepares a table/partition for a direct path operation. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathPrepare( OCIDirPathCtx *dpctx, OCISvcCtx *svchp, + OCIError *errhp ); + +/* + NAME + OCIDirPathLoadStream - OCI: Load a direct path stream. + + DESCRIPTION + Load a direct path stream to the object associated with + the direct path context. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathLoadStream( OCIDirPathCtx *dpctx, OCIDirPathStream *dpstr, + OCIError *errhp ); + + +/*---------------------- OCIDirPathColArray Operations ----------------------*/ + +/* + NAME + OCIDirPathColArrayEntryGet - OCI: Get column array entry. + + DESCRIPTION + Column array function which is used to get a specified entry in + a column array. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayEntryGet( OCIDirPathColArray *dpca, OCIError *errhp, + ub4 rownum, ub2 colIdx, ub1 **cvalpp, ub4 *clenp, + ub1 *cflgp ); + +/* + NAME + OCIDirPathColArrayEntrySet - OCI: Set column array entry. + + DESCRIPTION + Column array function which is used to set a specified entry in + a column array. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayEntrySet( OCIDirPathColArray *dpca, OCIError *errhp, + ub4 rownum, ub2 colIdx, ub1 *cvalp, ub4 clen, + ub1 cflg ); + +/* + NAME + OCIDirPathColArrayRowGet - OCI: Get column array row pointers. + + DESCRIPTION + Column array function which is used to get the base row pointers + for a specified row in a column array. + To be used in lieu of OCIDirPathColArrayEntryGet() and + OCIDirPathColArrayEntrySet(). + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayRowGet( OCIDirPathColArray *dpca, OCIError *errhp, + ub4 rownum, ub1 ***cvalppp, ub4 **clenpp, + ub1 **cflgpp ); + +/* + NAME + OCIDirPathColArrayReset - OCI: Reset Column Array State + + DESCRIPTION + Function which resets the column array state. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + Resetting the column array state is necessary when piecing in a large + column and an error occurs in the middle of loading the column. + */ +sword +OCIDirPathColArrayReset( OCIDirPathColArray *dpca, OCIError *errhp ); + +/* + NAME + OCIDirPathColArrayToStream - OCI: Convert Column Array to Stream Format. + + DESCRIPTION + Convert from column array format to stream format which is suitable + for loading via OCIDirPathLoadStream(). + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayToStream( OCIDirPathColArray *dpca, OCIDirPathCtx *dpctx, + OCIDirPathStream *dpstr, OCIError *errhp, + ub4 rowcnt, ub4 rowoff ); + + + +/*----------------------- OCIDirPathStream Operations -----------------------*/ + +/* + NAME + OCIDirPathStreamReset - OCI: + + DESCRIPTION + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathStreamReset( OCIDirPathStream *dpstr, OCIError *errhp ); + +#endif /* OCI8DP_ORACLE */ diff --git a/OCI/include/ociap.h b/OCI/include/ociap.h new file mode 100644 index 0000000..4f9aa9b --- /dev/null +++ b/OCI/include/ociap.h @@ -0,0 +1,11122 @@ +/* Copyright (c) 1996, 2008, Oracle. All rights reserved. */ + +/* + NAME + ociap.h + + DESCRIPTION + Oracle Call Interface - Ansi Prototypes + + RELATED DOCUMENTS + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + OCIAttrGet + OCIAttrSet + OCIBindArrayOfStruct + OCIBindByName + OCIBindByPos + OCIBindDynamic + OCIBindObject + OCIBreak + OCIConnectionPoolCreate + OCISessionPoolCreate + OCISessionGet + OCISessionRelease + OCIDateTimeAssign + OCIDateTimeCheck + OCIDateTimeCompare + OCIDateTimeConvert + OCIDateTimeFromText + OCIDateTimeGetDate + OCIDateTimeGetTime + OCIDateTimeGetTime + OCIDateTimeGetTimeZoneOffset + OCIDateTimeSysTimeStamp + OCIDateTimeIntervalAdd + OCIDateTimeIntervalSub + OCIDateTimeConstruct + OCIDateTimeSubtract + OCIDateTimeToText + OCIDateTimeGetTimeZoneName + OCIDateTimeToArray + OCIDateTimeFromArray + OCIRowidToChar + OCIDefineArrayOfStruct + OCIDefineByPos + OCIDefineDynamic + OCIDefineObject + OCIDescAlloc + OCIDescFree + OCIDescribeAny + OCIEnvCreate + OCIEnvNlsCreate + OCIEnvInit + OCIErrorGet + OCIExtractSetKey + OCIExtractFromFile + OCIIntervalSubtract + OCIIntervalMultiply + OCIIntervalToNumber + OCIIntervalToText + OCIIntervalFromTZ + OCIKerbAttrSet + OCILdaToSvcCtx + OCILobAppend + OCILobAssign + OCILobCharSetForm + OCILobCharSetId + OCILobCopy + OCILobCreateTemporary + OCILobDisableBuffering + OCILobEnableBuffering + OCILobErase + OCILobOpen + OCILobClose + OCILobFileClose + OCILobFileCLoseAll + OCILobFileExists + OCILobFileGetName + OCILobFileIsOpen + OCILobFileOpen + OCILobFileSetName + OCILobFlushBuffer + OCILobFreeTemporary + OCILobGetChunkSize + OCILobGetLength + OCILobIsEqual + OCILobIsTemporary + OCILobLoadFromFile + OCILobLocatorAssign + OCILobLocatorIsInit + OCILobRead + OCILobTrim + OCILobWrite + OCILobWriteAppend + OCILobGetStorageLimit + OCILobGetOptions + OCILobSetOptions + OCILobGetContentType + OCILobSetContentType + OCILogoff + OCILogon + OCILogon2 + OCIMemoryFree + OCIParamGet + OCIParamGet + OCIPasswordChange + OCIReset + OCIResultSetToStmt + OCIServerAttach + OCIServerDetach + OCIServerVersion + OCISessionBegin + OCISessionEnd + OCIStmtExecute + OCIStmtFetch + OCIStmtFetch2 + OCIStmtGetPieceInfo + OCIStmtPrepare + OCIStmtPrepare2 + OCIStmtRelease + OCIStmtSetPieceInfo + OCIFormatString + OCISvcCtxToLda + OCITransCommit + OCITransDetach + OCITransForget + OCITransMultiPrepare + OCITransPrepare + OCITransRollback + OCITransStart + OCIInitialize + OCIEnvCreate + OCIEnvNlsCreate + OCIFEnvCreate + OCIHandleAlloc + OCIDescriptorAlloc + OCIDescriptorFree + OCIArrayDescriptorAlloc + OCIArrayDescriptorFree + OCIEnvInit + OCIServerAttach + OCISessionBegin + OCISessionEnd + OCILogon + OCILogon2 + OCIPasswordChange + OCIStmtPrepare + OCIStmtPrepare2 + OCIStmtRelease + OCIBindByPos + OCIBindByName + OCIBindObject + OCIBindDynamic + OCIBindArrayOfStruct + OCIStmtGetPieceInfo + OCIStmtSetPieceInfo + OCIStmtExecute + OCIDefineByPos + OCIDefineObject + OCIDefineDynamic + OCIRowidToChar + OCIDefineArrayOfStruct + OCIStmtFetch + OCIStmtFetch2 + OCIStmtGetBindInfo + OCIDescribeAny + OCIParamGet + OCIParamSet + OCITransStart + OCITransMultiPrepare + OCIErrorGet + OCILobAppend + OCILobAssign + OCILobCharSetForm + OCILobCharSetId + OCILobCopy + OCILobCreateTemporary + OCILobClose + OCILobDisableBuffering + OCILobEnableBuffering + OCILobErase + OCILobFileClose + OCILobFileExists + OCILobFileGetName + OCILobFileIsOpen + OCILobFileOpen + OCILobFileSetName + OCILobFlushBuffer + OCILobFreeTemporary + OCILobGetChunkSize + OCILobGetLength + OCILobIsEqual + OCILobIsOpen + OCILobIsTemporary + OCILobLoadFromFile + OCILobLocatorAssign + OCILobLocatorIsInit + OCILobOpen + OCILobRead + OCILobTrim + OCILobWrite + OCILobWriteAppend + OCIServerVersion + OCIServerRelease + OCIAttrGet + OCIAttrSet + OCIUserCallbackRegister + OCIUserCallbackGet + OCISharedLibInit + OCIFileExists + OCIFileGetLength + OCIFileOpen + OCIFileRead + OCIFileSeek + OCIFileWrite + OCILobCopy2 + OCILobErase2 + OCILobGetLength2 + OCILobLoadFromFile2 + OCILobRead2 + OCILobArrayRead + OCILobTrim2 + OCILobWrite2 + OCILobArrayWrite + OCILobWriteAppend2 + OCILobGetStorageLimit + OCISecurityOpenWallet + OCISecurityCloseWallet + OCISecurityCreateWallet + OCISecurityDestroyWallet + OCISecurityStorePersona + OCISecurityOpenPersona + OCISecurityClosePersona + OCISecurityRemovePersona + OCISecurityCreatePersona + OCISecuritySetProtection + OCISecurityGetProtection + OCISecurityRemoveIdentity + OCISecurityCreateIdentity + OCISecurityAbortIdentity + OCISecurityFreeIdentity + OCISecurityStoreTrustedIdentity + OCISecuritySign + OCISecuritySignExpansion + OCISecurityVerify + OCISecurityValidate + OCISecuritySignDetached + OCISecuritySignDetExpansion + OCISecurityVerifyDetached + OCISecurity_PKEncrypt + OCISecurityPKEncryptExpansion + OCISecurityPKDecrypt + OCISecurityEncrypt + OCISecurityEncryptExpansion + OCISecurityDecrypt + OCISecurityEnvelope + OCISecurityDeEnvelope + OCISecurityKeyedHash + OCISecurityKeyedHashExpansion + OCISecurityHash + OCISecurityHashExpansion + OCISecuritySeedRandom + OCISecurityRandomBytes + OCISecurityRandomNumber + OCISecurityInitBlock + OCISecurityReuseBlock + OCISecurityPurgeBlock + OCISecuritySetBlock + OCISecurityGetIdentity + OCIAQEnq + OCIAQDeq + OCIAQEnqArray + OCIAQEnqStreaming + OCIAQDeqArray + OCIAQListen + OCIAQListen2 + OCIExtractSetKey + OCIExtractFromFile + OCIExtractToInt + OCIExtractToBool + OCIExtractToStr + OCIExtractToOCINum + OCIExtractFromList + OCIMemoryAlloc + OCIMemoryResize + OCIContextSetValue + OCIContextGetValue + OCIContextClearValue + OCIMemorySetCurrentIDs + OCIPicklerTdsCtxInit + OCIPicklerTdsInit + OCIPicklerTdsCreateElementNumber + OCIPicklerTdsCreateElementChar + OCIPicklerTdsCreateElementVarchar + OCIPicklerTdsCreateElementRaw + OCIPicklerTdsCreateElement + OCIPicklerTdsAddAttr + OCIPicklerTdsGenerate + OCIPicklerTdsGetAttr + OCIPicklerFdoInit + OCIPicklerFdoFree + OCIPicklerImageInit + OCIPicklerImageFree + OCIPicklerImageAddScalar + OCIPicklerImageAddNullScalar + OCIPicklerImageGenerate + OCIPicklerImageGetScalarSize + OCIPicklerImageGetScalar + OCIPicklerImageCollBegin + OCIPicklerImageCollAddScalar + OCIPicklerImageCollEnd + OCIPicklerImageCollBeginScan + OCIPicklerImageCollGetScalarSize + OCIPicklerImageCollGetScalar + OCIAnyDataGetType + OCIAnyDataIsNull + OCIAnyDataConvert + OCIAnyDataBeginCreate + OCIAnyDataAttrSet + OCIAnyDataCollAddElem + OCIAnyDataEndCreate + OCIAnyDataAccess + OCIAnyDataGetCurrAttrNum + OCIAnyDataAttrGet + OCIAnyDataCollGetElem + OCIPicklerTdsCtxInit + OCIPicklerTdsInit + OCIPicklerTdsCreateElementNumber + OCIPicklerTdsCreateElementChar + OCIPicklerTdsCreateElementVarchar + OCIPicklerTdsCreateElementRaw + OCIPicklerTdsCreateElement + OCIPicklerTdsAddAttr + OCIPicklerTdsGenerate + OCIPicklerTdsGetAttr + OCIPicklerFdoInit + OCIPicklerFdoFree + OCIPicklerImageInit + OCIPicklerImageFree + OCIPicklerImageAddScalar + OCIPicklerImageAddNullScalar + OCIPicklerImageGenerate + OCIPicklerImageGetScalarSize + OCIPicklerImageGetScalar + OCIPicklerImageCollBegin + OCIPicklerImageCollAddScalar + OCIPicklerImageCollEnd + OCIPicklerImageCollBeginScan + OCIPicklerImageCollGetScalarSize + OCIPicklerImageCollGetScalar + OCIAnyDataGetType + OCIAnyDataIsNull + OCIAnyDataConvert + OCIAnyDataBeginCreate + OCIAnyDataAttrSet + OCIAnyDataCollAddElem + OCIAnyDataEndCreate + OCIAnyDataAccess + OCIAnyDataGetCurrAttrNum + OCIAnyDataAttrGet + OCIAnyDataCollGetElem + OCIPicklerTdsCtxInit + OCIPicklerTdsInit + OCIPicklerTdsCreateElementNumber + OCIPicklerTdsCreateElementChar + OCIPicklerTdsCreateElementVarchar + OCIPicklerTdsCreateElementRaw + OCIPicklerTdsCreateElement + OCIPicklerTdsAddAttr + OCIPicklerTdsGenerate + OCIPicklerTdsGetAttr + OCIPicklerFdoInit + OCIPicklerFdoFree + OCIPicklerImageInit + OCIPicklerImageFree + OCIPicklerImageAddScalar + OCIPicklerImageAddNullScalar + OCIPicklerImageGenerate + OCIPicklerImageGetScalarSize + OCIPicklerImageGetScalar + OCIPicklerImageCollBegin + OCIPicklerImageCollAddScalar + OCIPicklerImageCollEnd + OCIPicklerImageCollBeginScan + OCIPicklerImageCollGetScalarSize + OCIPicklerImageCollGetScalar + OCIAnyDataGetType + OCIAnyDataIsNull + OCIAnyDataConvert + OCIAnyDataBeginCreate + OCIAnyDataAttrSet + OCIAnyDataCollAddElem + OCIAnyDataEndCreate + OCIAnyDataAccess + OCIAnyDataGetCurrAttrNum + OCIAnyDataAttrGet + OCIAnyDataCollGetElem + OCIAnyDataSetBeginCreate + OCIAnyDataSetDestroy + OCIAnyDataSetAddInstance + OCIAnyDataSetEndCreate + OCIAnyDataSetGetType + OCIAnyDataSetGetCount + OCIAnyDataSetGetInstance + OCIFormatString + OCINlsGetInfo + OCINlsNameMap + OCIMultiByteToWideChar + OCIMultiByteInSizeToWideChar + OCIWideCharToMultiByte + OCIWideCharInSizeToMultiByte + OCIWideCharStrcmp + OCIWideCharStrncmp + OCIWideCharStrcat + *OCIWideCharStrchr + OCIWideCharStrcpy + OCIWideCharStrncat + OCIWideCharStrncpy + *OCIWideCharStrrchr + OCIWideCharStrCaseConversion + OCIMultiByteStrcmp + OCIMultiByteStrncmp + OCIMultiByteStrcat + OCIMultiByteStrcpy + OCIMultiByteStrncat + OCIMultiByteStrncpy + OCIMultiByteStrnDisplayLength + OCIMultiByteStrCaseConversion + OCICharSetToUnicode + OCIUnicodeToCharSet + OCINlsCharSetConvert + OCINlsEnvironmentVariableGet + OCIMessageOpen + OCIMessageGet + OCIThreadMutexInit + OCIThreadMutexDestroy + OCIThreadMutexAcquire + OCIThreadMutexRelease + OCIThreadKeyInit + OCIThreadKeyDestroy + OCIThreadKeyGet + OCIThreadKeySet + OCIThreadIdSet + OCIThreadIdSetNull + OCIThreadIdGet + OCIThreadIdSame + OCIThreadIdNull + OCIThreadHndInit + OCIThreadHndDestroy + OCIThreadCreate + OCIThreadHandleGet + OCIThreadMutexInit + OCIThreadMutexDestroy + OCIThreadMutexAcquire + OCIThreadMutexRelease + OCIThreadKeyInit + OCIThreadKeyDestroy + OCIThreadKeyGet + OCIThreadKeySet + OCIThreadIdSet + OCIThreadIdSame + OCIThreadIdNull + OCIThreadCreate + OCISubscriptionRegister + OCISubscriptionPost + OCISubscriptionUnRegister + OCISubscriptionDisable + OCISubscriptionEnable + OCIDateTimeGetTime + OCIDateTimeGetDate + OCIDateTimeGetTimeZoneOffset + OCIDateTimeConstruct + OCIDateTimeSysTimeStamp + OCIDateTimeAssign + OCIDateTimeToText + OCIDateTimeFromText + OCIDateTimeCompare + OCIDateTimeCheck + OCIDateTimeConvert + OCIDateTimeSubtract + OCIDateTimeIntervalAdd + OCIDateTimeIntervalSub + OCIIntervalSubtract + OCIIntervalAdd + OCIIntervalMultiply + OCIIntervalDivide + OCIIntervalCompare + OCIIntervalFromNumber + OCIIntervalFromText + OCIIntervalToText + OCIIntervalToNumber + OCIIntervalCheck + OCIIntervalAssign + OCIIntervalSetYearMonth + OCIIntervalGetYearMonth + OCIIntervalSetDaySecond + OCIIntervalGetDaySecond + OCIDateTimeToArray + OCIDateTimeFromArray + OCIDateTimeGetTimeZoneName + OCIIntervalFromTZ + OCIConnectionPoolCreate + OCIConnectionPoolDestroy + OCISessionPoolCreate + OCISessionPoolDestroy + OCISessionGet + OCISessionRelease + OCIAppCtxSet + OCIAppCtxClearAll + OCIMemStats + OCIKerbAttrSet + OCIDBStartup + OCIDBShutdown + OCIClientVersion + OCIInitEventHandle + OCIStmtBindByPos + OCIStmtBindByName + + PRIVATE FUNCTION(S) + + EXAMPLES + + NOTES + + MODIFIED (MM/DD/YY) + slynn 03/18/08 - OCILobSet/SetContenttype->OCILobGet/SetContentType + amullick 02/11/08 - add OCILobGet/SetContenttype APIs + schoi 02/27/07 - OCILobGet/SetOptions API change + slynn 07/28/06 - Migrate to new 11g LOB terminology + hqian 05/22/06 - add OCI_SYSASM + slynn 06/21/06 - Add Lob Get Shared Regions Functionality + slynn 05/25/06 - New NG Lob Functionality. + jawilson 05/22/06 - add TDO out parameter for streaming enq callback + aramappa 01/19/06 - Added OCIArrayDescriptorAlloc, + OCIArrayDescriptorFree + jawilson 02/09/06 - add OCIAQEnqStreaming + mxu 03/08/06 - Fix bug 5037807 + srseshad 09/12/05 - stmtcache: callback + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + nbhatt 06/17/04 - merge conflicts + nbhatt 05/24/04 - merge conflicts + weiwang 05/06/04 - add OCIAQListen2 + rvissapr 06/21/04 - add OCIAppCtx API + debanerj 05/17/04 - 13064: LOB array Read and Write + aahluwal 06/02/04 - [OCI Events]: add OCIInitEventHandle + nikeda 05/28/04 - grabtrans 'nikeda_oci_events_copy' + nikeda 05/13/04 - [OCI Events] Rename HACBK->EVTCBK, HACTX->EVTCTX + nikeda 05/10/04 - [OCI Events] code review changes + aahluwal 04/09/04 - [OCI Events]: add OCIHAServerHandleGet + nikeda 03/18/04 - [OCI Events] New Server Handle Callback + dfrumkin 12/04/03 - Add OCIDBStartup, OCIDBShutdown + jciminsk 12/12/03 - merge from RDBMS_MAIN_SOLARIS_031209 + sgollapu 06/26/03 - Change OCIPing prototype + sgollapu 05/05/03 - Add OCIPing + debanerj 01/16/03 - Bug 2753018: Lob Locator parameter for + OCILobGetStorageLimit + rpingte 05/06/04 - add OCIClientVersion + debanerj 08/26/03 - 6003: Lob interface changes + sgollapu 06/23/03 - Add OCIPing + debanerj 01/16/03 - Bug 2753018: Lob Locator parameter for + OCILobGetStorageLimit + tkeefe 02/17/03 - bug-2773794: Add new interface for setting Kerb attrs + ataracha 01/03/03 - Move OCIXMLType functions to ocixml.h + akatti 11/28/02 - [2521361]:add OCIRowidToChar prototype + chliang 10/23/02 - add OCIFetchRowCallback + cparampa 10/13/02 - Fix the prototype of OCIAQListen(ansi prototype) + chliang 10/12/02 - add OCIBindRowCallback + debanerj 09/30/02 - Unlimited size LOB 6003 + thoang 09/25/02 - Add csid to XMLType create functions + thoang 04/19/02 - Add OCIXMLTypeGetNS + aahluwal 08/09/02 - adding OCIAQDeqArray + aahluwal 06/03/02 - bug 2360115 + skabraha 04/16/02 - fix compiler warnings + sichandr 02/12/02 - fix OCIXMLTypeExists + gayyappa 02/01/02 - fix 2210776 : change Dom to DOM + sichandr 10/24/01 - OCISvcCtx for XMLType create routines + schandir 09/14/01 - Add prototypes for Stmt Caching + abande 09/04/01 - Add Prototypes for Session Pooling Methods + stakeda 09/12/01 - add OCINlsCharSetConvert + whe 08/28/01 - add OCIEnvNlsCreate + wzhang 08/22/01 - Add OCINlsCharSetNameToId. + whe 10/05/01 - add prototype for OCIXMLType functions + mdmehta 04/06/01 - Bug 1683763, OCIDateTimeToText: buf_size to ub4* + schandir 12/12/00 - modify the ociconnectionpoolcreate() interface. + porangas 12/04/00 - Forward merge bug#974710 to 9i + rpingte 11/29/00 - Fix bug# 1485795. + gtarora 11/30/00 - fix comment for OCILobIsTemporary + akatti 11/07/00 - [1198379]:add OCIRowidToChar + bpalaval 10/15/00 - Forward merge 892654. + kmohan 09/18/00 - add OCILogon2 + etucker 07/28/00 - add OCIIntervalFromTZ + vjayaram 07/18/00 - add connection pooling changes + etucker 07/13/00 - add dls apis for oci + hmasaki 07/05/00 - fix 1230846: forward merge into 8.2 + mbastawa 06/05/00 - add OCIStmtFetch2 + rxgovind 06/07/00 - update OCIAnyData interfaces + rxgovind 05/04/00 - add OCIAnyDataSet interfaces + rkasamse 05/01/00 - remove attrno from OCIAnyDataAttrGet + rkasamse 03/13/00 - add prototype s for OCCIAnyData + slari 09/01/99 - remove OCIEnvCallback + slari 08/23/99 - add OCIUcb in user callback functions + dsaha 07/07/99 - Add OCIFEnvCreate for forms + vyanaman 06/21/99 - Change OCI DateTime/Interval APIs. + esoyleme 07/01/99 - expose MTS performance enhancements + whe 06/14/99 - bug727872:add CONST to match definitions + kkarun 02/23/99 - Fix OCIDateTime APIs + jiyang 12/07/98 - Add comments for OCI_NLS_DUAL_CURRENCY + aroy 12/01/98 - add OCIEnvCreate + slari 11/23/98 - use ORASTDARG + slari 11/21/98 - replace ellipsis by arglist in OCIUserCallback + thchang 10/20/98 - correct comment on OCILobCreateTemporary + slari 09/08/98 - allow envh to receive error info also in CallbackReg/ + kkarun 09/02/98 - Change const to CONST + aroy 08/04/98 - add OCITerminate calls + nramakri 06/25/98 - remove CONST from some OCIPickler APIs + jiyang 06/22/98 - Fix a lint error + nmallava 06/08/98 - ociistemporary -> envhp + jhasenbe 05/27/98 - Remove definitions for U-Calls (Unicode) + nmallava 05/18/98 - add comments + sgollapu 05/19/98 - Change text to OraText + aroy 04/20/98 - merge forward 8.0.5 -> 8.1.3 + nbhatt 05/14/98 - aq listen call + lchidamb 03/02/98 - Client Notification prototypes + vyanaman 04/19/98 - System Timestamp + kkarun 04/17/98 - Add more Interval functions + vyanaman 04/17/98 - Fix min (proc error) + vyanaman 04/16/98 - Add get/set TZ + kkarun 04/13/98 - Add Datetime prototypes + rkasamse 04/13/98 - change OCIEnv* to dvoid* for context/memory cart serv + rkasamse 04/15/98 - chage pickler cart interface + slari 03/20/98 - change proto of OCIUserCallback + slari 02/17/98 - add OCIUserCallback + jiyang 04/02/98 - Accept both env and user handles for NLS + rkasamse 03/20/98 - remove prototypes for OCIMemoryDuration* functions. + tsaulys 03/20/98 - use environment or session handle + nmallava 04/09/98 - OCILobLocatorAssign + nmallava 04/07/98 - lobgetchunksize and writeappend apis + jhasenbe 04/06/98 - Add new interfaces for Unicode support + nmallava 03/17/98 - add interfaces + nmallava 03/16/98 - add open/close apis + nmallava 03/10/98 - add temporary lobs apis + sgollapu 07/10/97 - Add OCIReset + sgollapu 02/09/98 - OCI non-blocking + nramakri 01/16/98 - remove #ifdef NEVER clause for OCIExtract + rmurthy 01/08/98 - OCIContextGenerateKey: change ub1 to ub4 + ewaugh 12/18/97 - Turn type wrappers into functions. + skabraha 12/02/97 - adding OCIFile functions + rhwu 12/02/97 - add OCI Thread + nramakri 12/15/97 - move to core4 + nramakri 12/11/97 - modify OCIExtract prototype + ewaugh 12/10/97 - add OCIFormat prototypes + nmallava 12/17/97 - Add ilob open and close apis + rkasamse 12/03/97 - Change some of the function names for pickler cartrid + nramakri 11/12/97 - add OCIExtract prototypes + rkasamse 11/21/97 - add prototypes for memory cartridge services and cont + rkasamse 11/03/97 - Add pickler cartridge interfaces. + jiyang 11/11/97 - Add NLS service for cartridge + tanguyen 08/19/97 - + cxcheng 07/30/97 - replace OCISvcCtx with OCISvcCtx + schandra 06/25/97 - AQ OCI interface + bnainani 07/21/97 - add prototypes for Oracle XA extensions + esoyleme 05/13/97 - move failover callback prototype + skmishra 05/06/97 - stdc compiler fixes + skmishra 04/24/97 - C++ Compatibility changes + skotsovo 04/21/97 - make lob parameter names consistent + rwhitman 04/16/97 - Fix LOB prototypes - Olint OCI 8.0.3 + ramkrish 04/15/97 - Add free flag to OCILobFlushBuffer + dchatter 04/10/97 - add nzt.h inclusion + cxcheng 04/09/97 - change objnamp from CONST text* to dvoid* + cxcheng 04/08/97 - fix prototype of OCIDescribeAny() + skotsovo 03/31/97 - remove OCILobLocatorSize + skotsovo 03/27/97 - add OCILobLoadFromFile + bcchang 02/18/97 - Fix syntax error + dchatter 01/13/97 - fix comments on LOB calls + aroy 01/10/97 - remove ocilobfilecreate delete + sgollapu 12/27/96 - Correct OCILogon prototype + dchatter 01/04/97 - comments to describe the functions + sgollapu 11/25/96 - Change OCILobFileIsExistent + schandra 11/18/96 - Remove xa.h include + sgollapu 11/09/96 - Change prototype of OCIDescribeAny + dchatter 10/31/96 - delete CONST from lob write cb fn + dchatter 10/30/96 - more changes + dchatter 10/26/96 - lob/file long name corrections + slari 10/16/96 - delete unused calls + rwessman 10/29/96 - Fixed OCISecurityGetIdentity prototype + bcchang 10/25/96 - Fix syntax error + sgollapu 10/22/96 - Add OCILogon and OCILogoff + rwessman 10/16/96 - Added cryptographic and digital signature functions + sgollapu 10/10/96 - Add ocibdp and ocibdn + rxgovind 10/07/96 - add oci file calls + skotsovo 10/01/96 - move orl lob fnts to oci + skotsovo 09/20/96 - in OCILobGetLength(), remove the 'isnull' parameter. + aroy 08/29/96 - change prototype for Nchar Lob support + dchatter 08/21/96 - OCIResultSetToStmt prototype change + sthakur 08/14/96 - add OCIParamSet + schandra 07/26/96 - TX OCI return values - sb4->sword + aroy 07/17/96 - terminology change: OCILobLocator => OCILobLocator + dchatter 07/01/96 - create ANSI prototypes + dchatter 07/01/96 - Creation + +*/ + + +#ifndef OCIAP_ORACLE +# define OCIAP_ORACLE + +# ifndef ORATYPES +# include +# endif + +#ifndef ORASTDARG +#include +#define ORASTDARG +#endif + +#ifndef OCIDFN +#include +#endif + +#ifndef NZT_ORACLE +#include +#endif /* NZT_ORACLE */ + +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#include +#endif + + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + +/***************************************************************************** + DESCRIPTION +****************************************************************************** +Note: the descriptions of the functions are alphabetically arranged. Please +maintain the arrangement when adding a new function description. The actual +prototypes are below this comment section and donot follow any alphabetical +ordering. + + +--------------------------------OCIAttrGet------------------------------------ + +OCIAttrGet() +Name +OCI Attribute Get +Purpose +This call is used to get a particular attribute of a handle. +Syntax +sword OCIAttrGet ( const void *trgthndlp, + ub4 trghndltyp, + void *attributep, + ub4 *sizep, + ub4 attrtype, + OCIError *errhp ); +Comments +This call is used to get a particular attribute of a handle. +See Appendix B, "Handle Attributes", for a list of handle types and their +readable attributes. +Parameters +trgthndlp (IN) - is the pointer to a handle type. +trghndltyp (IN) - is the handle type. +attributep (OUT) - is a pointer to the storage for an attribute value. The +attribute value is filled in. +sizep (OUT) - is the size of the attribute value. +This can be passed in as NULL for most parameters as the size is well known. +For text* parameters, a pointer to a ub4 must be passed in to get the length +of the string. +attrtype (IN) - is the type of attribute. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions +OCIAttrSet() + +--------------------------------OCIAttrSet------------------------------------ + + +OCIAttrSet() +Name +OCI Attribute Set +Purpose +This call is used to set a particular attribute of a handle or a descriptor. +Syntax +sword OCIAttrSet ( void *trgthndlp, + ub4 trghndltyp, + void *attributep, + ub4 size, + ub4 attrtype, + OCIError *errhp ); +Comments +This call is used to set a particular attribute of a handle or a descriptor. +See Appendix B for a list of handle types and their writeable attributes. +Parameters +trghndlp (IN/OUT) - the pointer to a handle type whose attribute gets +modified. +trghndltyp (IN/OUT) - is the handle type. +attributep (IN) - a pointer to an attribute value. +The attribute value is copied into the target handle. If the attribute value +is a pointer, then only the pointer is copied, not the contents of the pointer. +size (IN) - is the size of an attribute value. This can be passed in as 0 for +most attributes as the size is already known by the OCI library. For text* +attributes, a ub4 must be passed in set to the length of the string. +attrtype (IN) - the type of attribute being set. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions +OCIAttrGet() + + + +--------------------------------OCIBindArrayOfStruct-------------------------- + + + +OCIBindArrayOfStruct() +Name +OCI Bind for Array of Structures +Purpose +This call sets up the skip parameters for a static array bind. +Syntax +sword OCIBindArrayOfStruct ( OCIBind *bindp, + OCIError *errhp, + ub4 pvskip, + ub4 indskip, + ub4 alskip, + ub4 rcskip ); +Comments +This call sets up the skip parameters necessary for a static array bind. +This call follows a call to OCIBindByName() or OCIBindByPos(). The bind +handle returned by that initial bind call is used as a parameter for the +OCIBindArrayOfStruct() call. +For information about skip parameters, see the section "Arrays of Structures" +on page 4-16. +Parameters +bindp (IN) - the handle to a bind structure. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +pvskip (IN) - skip parameter for the next data value. +indskip (IN) - skip parameter for the next indicator value or structure. +alskip (IN) - skip parameter for the next actual length value. +rcskip (IN) - skip parameter for the next column-level return code value. +Related Functions +OCIAttrGet() + + +--------------------------------OCIBindByName--------------------------------- + +OCIBindByName() +Name +OCI Bind by Name +Purpose +Creates an association between a program variable and a placeholder in a SQL +statement or PL/SQL block. +Syntax +sword OCIBindByName ( + OCIStmt *stmtp, + OCIBind **bindp, + OCIError *errhp, + const OraText *placeholder, + sb4 placeh_len, + void *valuep, + sb4 value_sz, + ub2 dty, + void *indp, + ub2 *alenp, + ub2 *rcodep, + ub4 maxarr_len, + ub4 *curelep, + ub4 mode ); +Description +This call is used to perform a basic bind operation. The bind creates an +association between the address of a program variable and a placeholder in a +SQL statement or PL/SQL block. The bind call also specifies the type of data +which is being bound, and may also indicate the method by which data will be +provided at runtime. +This function also implicitly allocates the bind handle indicated by the bindp +parameter. +Data in an OCI application can be bound to placeholders statically or +dynamically. Binding is static when all the IN bind data and the OUT bind +buffers are well-defined just before the execute. Binding is dynamic when the +IN bind data and the OUT bind buffers are provided by the application on +demand at execute time to the client library. Dynamic binding is indicated by +setting the mode parameter of this call to OCI_DATA_AT_EXEC. +Related Functions: For more information about dynamic binding, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16. +Both OCIBindByName() and OCIBindByPos() take as a parameter a bind handle, +which is implicitly allocated by the bind call A separate bind handle is +allocated for each placeholder the application is binding. +Additional bind calls may be required to specify particular attributes +necessary when binding certain data types or handling input data in certain +ways: +If arrays of structures are being utilized, OCIBindArrayOfStruct() must +be called to set up the necessary skip parameters. +If data is being provided dynamically at runtime, and the application +will be using user-defined callback functions, OCIBindDynamic() must +be called to register the callbacks. +If a named data type is being bound, OCIBindObject() must be called to +specify additional necessary information. +Parameters +stmth (IN/OUT) - the statement handle to the SQL or PL/SQL statement +being processed. +bindp (IN/OUT) - a pointer to a pointer to a bind handle which is implicitly +allocated by this call. The bind handle maintains all the bind information +for this particular input value. The handle is feed implicitly when the +statement handle is deallocated. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +placeholder (IN) - the placeholder attributes are specified by name if +ocibindn() is being called. +placeh_len (IN) - the length of the placeholder name specified in placeholder. +valuep (IN/OUT) - a pointer to a data value or an array of data values of the +type specified in the dty parameter. An array of data values can be specified +for mapping into a PL/SQL table or for providing data for SQL multiple-row +operations. When an array of bind values is provided, this is called an array +bind in OCI terms. Additional attributes of the array bind (not bind to a +column of ARRAY type) are set up in OCIBindArrayOfStruct() call. +For a REF, named data type bind, the valuep parameter is used only for IN +bind data. The pointers to OUT buffers are set in the pgvpp parameter +initialized by OCIBindObject(). For named data type and REF binds, the bind +values are unpickled into the Object Cache. The OCI object navigational calls +can then be used to navigate the objects and the refs in the Object Cache. +If the OCI_DATA_AT_EXEC mode is specified in the mode parameter, valuep +is ignored for all data types. OCIBindArrayOfStruct() cannot be used and +OCIBindDynamic() must be invoked to provide callback functions if desired. +value_sz (IN) - the size of a data value. In the case of an array bind, this is +the maximum size of any element possible with the actual sizes being specified +in the alenp parameter. +If the OCI_DATA_AT_EXEC mode is specified, valuesz defines the maximum +size of the data that can be ever provided at runtime for data types other than +named data types or REFs. +dty (IN) - the data type of the value(s) being bound. Named data types +(SQLT_NTY) and REFs (SQLT_REF) are valid only if the application has been +initialized in object mode. For named data types, or REFs, additional calls +must be made with the bind handle to set up the datatype-specific attributes. +indp (IN/OUT) - pointer to an indicator variable or array. For scalar data +types, this is a pointer to sb2 or an array of sb2s. For named data types, +this pointer is ignored and the actual pointer to the indicator structure or +an array of indicator structures is initialized by OCIBindObject(). +Ignored for dynamic binds. +See the section "Indicator Variables" on page 2-43 for more information about +indicator variables. +alenp (IN/OUT) - pointer to array of actual lengths of array elements. Each +element in alenp is the length of the data in the corresponding element in the +bind value array before and after the execute. This parameter is ignored for +dynamic binds. +rcodep (OUT) - pointer to array of column level return codes. This parameter +is ignored for dynamic binds. +maxarr_len (IN) - the maximum possible number of elements of type dty in a +PL/SQL binds. This parameter is not required for non-PL/SQL binds. If +maxarr_len is non-zero, then either OCIBindDynamic() or +OCIBindArrayOfStruct() can be invoked to set up additional bind attributes. +curelep(IN/OUT) - a pointer to the actual number of elements. This parameter +is only required for PL/SQL binds. +mode (IN) - the valid modes for this parameter are: +OCI_DEFAULT. This is default mode. +OCI_DATA_AT_EXEC. When this mode is selected, the value_sz +parameter defines the maximum size of the data that can be ever +provided at runtime. The application must be ready to provide the OCI +library runtime IN data buffers at any time and any number of times. +Runtime data is provided in one of the two ways: +callbacks using a user-defined function which must be registered +with a subsequent call to OCIBindDynamic(). +a polling mechanism using calls supplied by the OCI. This mode +is assumed if no callbacks are defined. +For more information about using the OCI_DATA_AT_EXEC mode, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16. +When the allocated buffers are not required any more, they should be +freed by the client. +Related Functions +OCIBindDynamic(), OCIBindObject(), OCIBindArrayOfStruct(), OCIAttrGet() + + + +-------------------------------OCIBindByPos----------------------------------- + + +OCIBindByPos() +Name +OCI Bind by Position +Purpose +Creates an association between a program variable and a placeholder in a SQL +statement or PL/SQL block. +Syntax +sword OCIBindByPos ( + OCIStmt *stmtp, + OCIBind **bindp, + OCIError *errhp, + ub4 position, + void *valuep, + sb4 value_sz, + ub2 dty, + void *indp, + ub2 *alenp, + ub2 *rcodep, + ub4 maxarr_len, + ub4 *curelep, + ub4 mode); + +Description +This call is used to perform a basic bind operation. The bind creates an +association between the address of a program variable and a placeholder in a +SQL statement or PL/SQL block. The bind call also specifies the type of data +which is being bound, and may also indicate the method by which data will be +provided at runtime. +This function also implicitly allocates the bind handle indicated by the bindp +parameter. +Data in an OCI application can be bound to placeholders statically or +dynamically. Binding is static when all the IN bind data and the OUT bind +buffers are well-defined just before the execute. Binding is dynamic when the +IN bind data and the OUT bind buffers are provided by the application on +demand at execute time to the client library. Dynamic binding is indicated by +setting the mode parameter of this call to OCI_DATA_AT_EXEC. +Related Functions: For more information about dynamic binding, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16 +Both OCIBindByName() and OCIBindByPos() take as a parameter a bind handle, +which is implicitly allocated by the bind call A separate bind handle is +allocated for each placeholder the application is binding. +Additional bind calls may be required to specify particular attributes +necessary when binding certain data types or handling input data in certain +ways: +If arrays of structures are being utilized, OCIBindArrayOfStruct() must +be called to set up the necessary skip parameters. +If data is being provided dynamically at runtime, and the application +will be using user-defined callback functions, OCIBindDynamic() must +be called to register the callbacks. +If a named data type is being bound, OCIBindObject() must be called to +specify additional necessary information. +Parameters +stmth (IN/OUT) - the statement handle to the SQL or PL/SQL statement +being processed. +bindp (IN/OUT) - a pointer to a pointer to a bind handle which is implicitly +allocated by this call. The bind handle maintains all the bind information +for this particular input value. The handle is feed implicitly when the +statement handle is deallocated. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +position (IN) - the placeholder attributes are specified by position if +ocibindp() is being called. +valuep (IN/OUT) - a pointer to a data value or an array of data values of the +type specified in the dty parameter. An array of data values can be specified +for mapping into a PL/SQL table or for providing data for SQL multiple-row +operations. When an array of bind values is provided, this is called an array +bind in OCI terms. Additional attributes of the array bind (not bind to a +column of ARRAY type) are set up in OCIBindArrayOfStruct() call. +For a REF, named data type bind, the valuep parameter is used only for IN +bind data. The pointers to OUT buffers are set in the pgvpp parameter +initialized by OCIBindObject(). For named data type and REF binds, the bind +values are unpickled into the Object Cache. The OCI object navigational calls +can then be used to navigate the objects and the refs in the Object Cache. +If the OCI_DATA_AT_EXEC mode is specified in the mode parameter, valuep +is ignored for all data types. OCIBindArrayOfStruct() cannot be used and +OCIBindDynamic() must be invoked to provide callback functions if desired. +value_sz (IN) - the size of a data value. In the case of an array bind, this is +the maximum size of any element possible with the actual sizes being specified +in the alenp parameter. +If the OCI_DATA_AT_EXEC mode is specified, valuesz defines the maximum +size of the data that can be ever provided at runtime for data types other than +named data types or REFs. +dty (IN) - the data type of the value(s) being bound. Named data types +(SQLT_NTY) and REFs (SQLT_REF) are valid only if the application has been +initialized in object mode. For named data types, or REFs, additional calls +must be made with the bind handle to set up the datatype-specific attributes. +indp (IN/OUT) - pointer to an indicator variable or array. For scalar data +types, this is a pointer to sb2 or an array of sb2s. For named data types, +this pointer is ignored and the actual pointer to the indicator structure or +an array of indicator structures is initialized by OCIBindObject(). Ignored +for dynamic binds. +See the section "Indicator Variables" on page 2-43 for more information about +indicator variables. +alenp (IN/OUT) - pointer to array of actual lengths of array elements. Each +element in alenp is the length of the data in the corresponding element in the +bind value array before and after the execute. This parameter is ignored for +dynamic binds. +rcodep (OUT) - pointer to array of column level return codes. This parameter +is ignored for dynamic binds. +maxarr_len (IN) - the maximum possible number of elements of type dty in a +PL/SQL binds. This parameter is not required for non-PL/SQL binds. If +maxarr_len is non-zero, then either OCIBindDynamic() or +OCIBindArrayOfStruct() can be invoked to set up additional bind attributes. +curelep(IN/OUT) - a pointer to the actual number of elements. This parameter +is only required for PL/SQL binds. +mode (IN) - the valid modes for this parameter are: +OCI_DEFAULT. This is default mode. +OCI_DATA_AT_EXEC. When this mode is selected, the value_sz +parameter defines the maximum size of the data that can be ever +provided at runtime. The application must be ready to provide the OCI +library runtime IN data buffers at any time and any number of times. +Runtime data is provided in one of the two ways: +callbacks using a user-defined function which must be registered +with a subsequent call to OCIBindDynamic() . +a polling mechanism using calls supplied by the OCI. This mode +is assumed if no callbacks are defined. +For more information about using the OCI_DATA_AT_EXEC mode, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16. +When the allocated buffers are not required any more, they should be +freed by the client. +Related Functions +OCIBindDynamic(), OCIBindObject(), OCIBindArrayOfStruct(), OCIAttrGet() + + + +-------------------------------OCIBindDynamic--------------------------------- + +OCIBindDynamic() +Name +OCI Bind Dynamic Attributes +Purpose +This call is used to register user callbacks for dynamic data allocation. +Syntax +sword OCIBindDynamic( OCIBind *bindp, + OCIError *errhp, + void *ictxp, + OCICallbackInBind (icbfp)( + void *ictxp, + OCIBind *bindp, + ub4 iter, + ub4 index, + void **bufpp, + ub4 *alenp, + ub1 *piecep, + void **indp ), + void *octxp, + OCICallbackOutBind (ocbfp)( + void *octxp, + OCIBind *bindp, + ub4 iter, + ub4 index, + void **bufp, + ub4 **alenpp, + ub1 *piecep, + void **indpp, + ub2 **rcodepp) ); +Comments +This call is used to register user-defined callback functions for providing +data for an UPDATE or INSERT if OCI_DATA_AT_EXEC mode was specified in a +previous call to OCIBindByName() or OCIBindByPos(). +The callback function pointers must return OCI_CONTINUE if it the call is +successful. Any return code other than OCI_CONTINUE signals that the client +wishes to abort processing immediately. +For more information about the OCI_DATA_AT_EXEC mode, see the section +"Runtime Data Allocation and Piecewise Operations" on page 5-16. +Parameters +bindp (IN/OUT) - a bind handle returned by a call to OCIBindByName() or +OCIBindByPos(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +ictxp (IN) - the context pointer required by the call back function icbfp. +icbfp (IN) - the callback function which returns a pointer to the IN bind +value or piece at run time. The callback takes in the following parameters. +ictxp (IN/OUT) - the context pointer for this callback function. +bindp (IN) - the bind handle passed in to uniquely identify this bind +variable. +iter (IN) - 1-based execute iteration value. +index (IN) - index of the current array, for an array bind. 1 based not +greater than curele parameter of the bind call. +index (IN) - index of the current array, for an array bind. This parameter +is 1-based, and may not be greater than curele parameter of the bind call. +bufpp (OUT) - the pointer to the buffer. +piecep (OUT) - which piece of the bind value. This can be one of the +following values - OCI_ONE_PIECE, OCI_FIRST_PIECE, +OCI_NEXT_PIECE and OCI_LAST_PIECE. +indp (OUT) - contains the indicator value. This is apointer to either an +sb2 value or a pointer to an indicator structure for binding named data +types. +indszp (OUT) - contains the indicator value size. A pointer containing +the size of either an sb2 or an indicator structure pointer. +octxp (IN) - the context pointer required by the callback function ocbfp. +ocbfp (IN) - the callback function which returns a pointer to the OUT bind +value or piece at run time. The callback takes in the following parameters. +octxp (IN/OUT) - the context pointer for this call back function. +bindp (IN) - the bind handle passed in to uniquely identify this bind +variable. +iter (IN) - 1-based execute iteration value. +index (IN) - index of the current array, for an array bind. This parameter +is 1-based, and must not be greater than curele parameter of the bind call. +bufpp (OUT) - a pointer to a buffer to write the bind value/piece. +buflp (OUT) - returns the buffer size. +alenpp (OUT) - a pointer to a storage for OCI to fill in the size of the bind +value/piece after it has been read. +piecep (IN/OUT) - which piece of the bind value. It will be set by the +library to be one of the following values - OCI_ONE_PIECE or +OCI_NEXT_PIECE. The callback function can leave it unchanged or set +it to OCI_FIRST_PIECE or OCI_LAST_PIECE. By default - +OCI_ONE_PIECE. +indpp (OUT) - returns a pointer to contain the indicator value which +either an sb2 value or a pointer to an indicator structure for named data +types. +indszpp (OUT) - returns a pointer to return the size of the indicator +value which is either size of an sb2 or size of an indicator structure. +rcodepp (OUT) - returns a pointer to contains the return code. +Related Functions +OCIAttrGet() + + +---------------------------------OCIBindObject-------------------------------- + + +OCIBindObject() +Name +OCI Bind Object +Purpose +This function sets up additional attributes which are required for a named +data type (object) bind. +Syntax +sword OCIBindObject ( OCIBind *bindp, + OCIError *errhp, + const OCIType *type, + void **pgvpp, + ub4 *pvszsp, + void **indpp, + ub4 *indszp, ); +Comments +This function sets up additional attributes which binding a named data type +or a REF. An error will be returned if this function is called when the OCI +environment has been initialized in non-object mode. +This call takes as a paramter a type descriptor object (TDO) of datatype +OCIType for the named data type being defined. The TDO can be retrieved +with a call to OCITypeByName(). +If the OCI_DATA_AT_EXEC mode was specified in ocibindn() or ocibindp(), the +pointers to the IN buffers are obtained either using the callback icbfp +registered in the OCIBindDynamic() call or by the OCIStmtSetPieceInfo() call. +The buffers are dynamically allocated for the OUT data and the pointers to +these buffers are returned either by calling ocbfp() registered by the +OCIBindDynamic() or by setting the pointer to the buffer in the buffer passed +in by OCIStmtSetPieceInfo() called when OCIStmtExecute() returned +OCI_NEED_DATA. The memory of these client library- allocated buffers must be +freed when not in use anymore by using the OCIObjectFreee() call. +Parameters +bindp ( IN/OUT) - the bind handle returned by the call to OCIBindByName() +or OCIBindByPos(). +errhp ( IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +type ( IN) - points to the TDO which describes the type of the program +variable being bound. Retrieved by calling OCITypeByName(). +pgvpp ( IN/OUT) - points to a pointer to the program variable buffer. For an +array, pgvpp points to an array of pointers. When the bind variable is also an +OUT variable, the OUT Named Data Type value or REF is allocated +(unpickled) in the Object Cache, and a pointer to the value or REF is returned, +At the end of execute, when all OUT values have been received, pgvpp points +to an array of pointer(s) to these newly allocated named data types in the +object cache. +pgvpp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the Named +Data Type buffers are requested at runtime. For static array binds, skip +factors may be specified using the OCIBindArrayOfStruct() call. The skip +factors are used to compute the address of the next pointer to the value, the +indicator structure and their sizes. +pvszsp ( IN/OUT) - points to the size of the program variable. The size of the +named data type is not required on input. For an array, pvszsp is an array of +ub4s. On return, for OUT bind variables, this points to size(s) of the Named +Data Types and REFs received. pvszsp is ignored if the OCI_DATA_AT_EXEC +mode is set. Then the size of the buffer is taken at runtime. +indpp ( IN/OUT) - points to a pointer to the program variable buffer +containing the parallel indicator structure. For an array, points to an array +of pointers. When the bind variable is also an OUT bind variable, memory is +allocated in the object cache, to store the unpickled OUT indicator values. At +the end of the execute when all OUT values have been received, indpp points +to the pointer(s) to these newly allocated indicator structure(s). +indpp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the indicator +is requested at runtime. +indszp ( IN/OUT) - points to the size of the IN indicator structure program +variable. For an array, it is an array of sb2s. On return for OUT bind +variables, this points to size(s) of the received OUT indicator structures. +indszp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the indicator +size is requested at runtime. +Related Functions +OCIAttrGet() + + + +----------------------------------OCIBreak------------------------------------ + + +OCIBreak() +Name +OCI Break +Purpose +This call performs an immediate (asynchronous) abort of any currently +executing OCI function that is associated with a server . +Syntax +sword OCIBreak ( void *hndlp, + OCIError *errhp); +Comments +This call performs an immediate (asynchronous) abort of any currently +executing OCI function that is associated with a server. It is normally used +to stop a long-running OCI call being processed on the server. +This call can take either the service context handle or the server context +handle as a parameter to identify the function to be aborted. +Parameters +hndlp (IN) - the service context handle or the server context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions + +-----------------------------OCIConnectionPoolCreate -------------------------- +Name: +OCIConnectionPoolCreate + +Purpose: +Creates the connections in the pool + +Syntax: +OCIConnectionPoolCreate (OCIEnv *envhp, OCIError *errhp, OCICPool *poolhp, + OraText **poolName, sb4 *poolNameLen, + const Oratext *dblink, sb4 dblinkLen, + ub4 connMin, ub4 connMax, ub4 connIncr, + const OraText *poolUsername, sb4 poolUserLen, + const OraText *poolPassword, sb4 poolPassLen, + ub4 mode) +Comments: +This call is used to create a connection pool. conn_min connections +to the database are started on calling OCIConnectionPoolCreate. + +Parameters: +envhp (IN/OUT) - A pointer to the environment where the Conencton Pool + is to be created +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +poolhp (IN/OUT) - An uninitialiazed pool handle. +poolName (OUT) - The connection pool name. +poolNameLen (OUT) - The length of the connection pool name +dblink (IN/OUT) - Specifies the database(server) to connect. This will also + be used as the default pool name. +dblinkLen (IN) - The length of the string pointed to by dblink. +connMin (IN) - Specifies the minimum number of connections in the + Connection Pool at any instant. + connMin number of connections are started when + OCIConnectionPoolCreate() is called. +connMax (IN) - Specifies the maximum number of connections that can be + opened to the database. Once this value is reached, no + more connections are opened. +connIncr (IN) - Allows application to set the next increment for + connections to be opened to the database if the current + number of connections are less than conn_max. +poolUsername (IN/OUT) - Connection pooling requires an implicit proxy + session and this attribute provides a username + for that session. +poolUserLen (IN) - This represents the length of pool_username. +poolPassword (IN/OUT) - The password for the parameter pool_username passed + above. +poolPassLen (IN) - This represents the length of pool_password. + +mode (IN) - The modes supported are OCI_DEFAULT and +OCI_CPOOL_REINITIALIZE + +Related Functions +OCIConnectionPoolDestroy() + +--------------------------------------------------------------------------- + +----------------------------OCIConnectionPoolDestroy------------------------- +Name: +OCIConnectionPoolDestroy + +Purpose: +Terminates the connections in the pool + +Syntax: +OCIConnectionPoolDestroy (OCICPool *poolhp, OCIError *errhp, ub4 mode) + +Comments: +On calling OCIConnectionPoolDestroy, all the open connections in the pool +are closed and the pool is destroyed. + +Parameters: +poolhp (IN/OUT) - An initialiazed pool handle. +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +mode (IN) - Currently, OCIConnectionPoolDestroy() will support only + the OCI_DEFAULT mode. + +Related Functions: +OCIConnectionPoolCreate() + +----------------------------------------------------------------------------- +----------------------------OCISessionPoolCreate----------------------------- +Name: +OCISessionPoolCreate + +Purpose: +Creates the sessions in the session pool. + +Syntax: +sword OCISessionPoolCreate (OCIEnv *envhp, OCIError *errhp, OCISpool *spoolhp, + OraText **poolName, ub4 *poolNameLen, + const OraText *connStr, ub4 connStrLen, + ub4 sessMin, ub4 sessMax, ub4 sessIncr, + OraText *userid, ub4 useridLen, + OraText *password, ub4 passwordLen, + ub4 mode) + +Comments: +When OCISessionPoolCreate is called, a session pool is initialized for +the associated environment and the database specified by the +connStr parameter. This pool is named uniquely and the name +is returned to the user in the poolname parameter. + +Parameters: +envhp (IN/OUT) - A pointer to the environment handle in which the session + pool needs to be created. +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +spoolhp (IN/OUT) - A pointer to the session pool handle that is created. +poolName (OUT) - Session pool name returned to the user. +poolNameLen (OUT) - Length of the PoolName +connStr (IN) - The TNS alias of the database to connect to. +connStrLen (IN) - Length of the connStr. +sessMin (IN) - Specifies the minimum number of sessions in the Session Pool. + These are the number of sessions opened in the beginning, if + in Homogeneous mode. Else, the parameter is ignored. +sessMax (IN) - Specifies the maximum number of sessions in the Session Pool. + Once this value is reached, no more sessions are opened, + unless the OCI_ATTR_SPOOL_FORCEGET is set. +userid (IN) - Specifies the userid with which to start up the sessions. +useridLen (IN) - Length of userid. +password (IN) - Specifies the password for the corresponding userid. +passwordLen (IN) - Specifies the length of the password +mode(IN) - May be OCI_DEFAULT, OCI_SPC_SPOOL_REINITIALIZE, or + OCI_SPC_SPOOL_HOMOGENEOUS. + +Returns: +SUCCESS - If pool could be allocated and created successfully. +ERROR - If above conditions could not be met. + +Related Functions: +OCISessionPoolDestroy() +----------------------------------------------------------------------------- +-----------------------------OCISessionPoolDestroy--------------------------- +Name: +OCISessionPoolDestroy + +Purpose: +Terminates all the sessions in the session pool. + +Syntax: +sword OCISessionPoolDestroy (OCISPool *spoolhp, OCIError *errhp, ub4 mode) + +Comments: +spoolhp (IN/OUT) - The pool handle of the session pool to be destroyed. +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +mode (IN) - Currently only OCI_DEFAULT mode is supported. + +Returns: +SUCCESS - All the sessions could be closed. +ERROR - If the above condition is not met. + +Related Functions: +OCISessionPoolCreate() +----------------------------------------------------------------------------- +-------------------------------OCISessionGet--------------------------------- +Name: +OCISessionGet + +Purpose: +Get a session. This could be from a session pool, connection pool or +a new standalone session. + +Syntax: +sword OCISessionGet(OCIenv *envhp, OCIError *errhp, OCISvcCtx **svchp, + OCIAuthInfo *authhp, + OraText *poolName, ub4 poolName_len, + const OraText *tagInfo, ub4 tagInfo_len, + OraText **retTagInfo, ub4 *retTagInfo_len, + boolean *found, + ub4 mode) + +Comments: +envhp (IN/OUT) - OCI environment handle. +errhp (IN/OUT) - OCI error handle to be passed to OCIErrorGet(). +svchp (IN/OUT) - Address of an OCI service context pointer. This will be + filled with a server and session handle, attached to the + pool. +authhp (IN/OUT) - OCI Authentication Information handle. +poolName (IN) - This indicates the session/connection pool to get the + session/connection from in the OCI_SPOOL/OCI_CPOOL mode. + In the OCI_DEFAULT mode it refers to the connect string. +poolName_len (IN) - length of poolName. +tagInfo (IN) - indicates the tag of the session that the user wants. If the + user wants a default session, he must specify a NULL here. + Only used for Session Pooling. +tagInfo_len (IN) - the length of tagInfo. +retTagInfo (OUT) - This indicates the type of session that is returned to + the user. Only used for Session Pooling. +retTagInfo_len (OUT) - the length of retTagInfo. +found (OUT) - set to true if the user gets a session he had requested, else + set to false. Only used for Session Pooling. +mode (IN) - The supported modes are OCI_DEFAULT, OCI_CRED_PROXY and + OCI_GET_SPOOL_MATCHANY, OCI_SPOOL and OCI_CPOOL. OCI_SPOOL and + OCI_CPOOL are mutually exclusive. + +Returns: +SUCCESS - if a session was successfully returned into svchp. +SUCCESS_WITH_INFO - if a session was successfully returned into svchp and the + total number of sessions > maxsessions. Only valid for + Session Pooling. +ERROR - If a session could not be retrieved. + +Related Functions: +OCISessionRelease() +----------------------------------------------------------------------------- +---------------------------OCISessionRelease--------------------------------- +Name: +OCISessionRelease + +Purpose: +Release the session. + +Syntax: +sword OCISessionRelease ( OCISvcCtx *svchp, OCIError *errhp, + OraText *tag, ub4 tag_len, + ub4 mode); + +Comments: +svchp (IN/OUT) - The service context associated with the session/connection. +errhp (IN/OUT) - OCI error handle to be passed to OCIErrorGet(). +tag (IN) - Only used for Session Pooling. + This parameter will be ignored unless mode OCI_RLS_SPOOL_RETAG is + specified. In this case, the session is labelled with this tag and + returned to the pool. If this is NULL, then the session is untagged. +tag_len (IN) - Length of the tag. This is ignored unless mode + OCI_RLS_SPOOL_RETAG is set. +mode (IN) - The supported modes are OCI_DEFAULT, OCI_RLS_SPOOL_DROPSESS, + OCI_RLS_SPOOL_RETAG. The last 2 are only valid for Session Pooling. + When OCI_RLS_SPOOL_DROPSESS is specified, the session + will be removed from the session pool. If OCI_RLS_SPOOL_RETAG + is set, the tag on the session will be altered. If this mode is + not set, the tag and tag_len parameters will be ignored. + +Returns: +ERROR - If the session could not be released successfully. +SUCCESS - In all other cases. + +Related Functions: +OCISessionGet(). +----------------------------------------------------------------------------- +------------------------------OCIDateTimeAssign -------------------------- +sword OCIDateTimeAssign(void *hndl, OCIError *err, const OCIDateTime *from, + OCIDateTime *to); +NAME: OCIDateTimeAssign - OCIDateTime Assignment +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +from (IN) - datetime to be assigned +to (OUT) - lhs of assignment +DESCRIPTION: + Performs date assignment. The type of the output will be same as that + of input + +------------------------------OCIDateTimeCheck---------------------------- +sword OCIDateTimeCheck(void *hndl, OCIError *err, const OCIDateTime *date, + ub4 *valid ); +NAME: OCIDateTimeCheck - OCIDateTime CHecK if the given date is valid +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date (IN) - date to be checked +valid (OUT) - returns zero for a valid date, otherwise + the ORed combination of all error bits specified below: + Macro name Bit number Error + ---------- ---------- ----- + OCI_DATE_INVALID_DAY 0x1 Bad day + OCI_DATE_DAY_BELOW_VALID 0x2 Bad DAy Low/high bit (1=low) + OCI_DATE_INVALID_MONTH 0x4 Bad MOnth + OCI_DATE_MONTH_BELOW_VALID 0x8 Bad MOnth Low/high bit (1=low) + OCI_DATE_INVALID_YEAR 0x10 Bad YeaR + OCI_DATE_YEAR_BELOW_VALID 0x20 Bad YeaR Low/high bit (1=low) + OCI_DATE_INVALID_HOUR 0x40 Bad HouR + OCI_DATE_HOUR_BELOW_VALID 0x80 Bad HouR Low/high bit (1=low) + OCI_DATE_INVALID_MINUTE 0x100 Bad MiNute + OCI_DATE_MINUTE_BELOW_VALID 0x200 Bad MiNute Low/high bit (1=low) + OCI_DATE_INVALID_SECOND 0x400 Bad SeCond + OCI_DATE_SECOND_BELOW_VALID 0x800 bad second Low/high bit (1=low) + OCI_DATE_DAY_MISSING_FROM_1582 0x1000 Day is one of those "missing" + from 1582 + OCI_DATE_YEAR_ZERO 0x2000 Year may not equal zero + OCI_DATE_INVALID_TIMEZONE 0x4000 Bad Timezone + OCI_DATE_INVALID_FORMAT 0x8000 Bad date format input + + So, for example, if the date passed in was 2/0/1990 25:61:10 in + (month/day/year hours:minutes:seconds format), the error returned + would be OCI_DATE_INVALID_DAY | OCI_DATE_DAY_BELOW_VALID | + OCI_DATE_INVALID_HOUR | OCI_DATE_INVALID_MINUTE + +DESCRIPTION: + Check if the given date is valid. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'date' and 'valid' pointers are NULL pointers + +------------------------------- OCIDateTimeCompare---------------------------- +sword OCIDateTimeCompare(void *hndl, OCIError *err, const OCIDateTime *date1, + const OCIDateTime *date2, sword *result ); +NAME: OCIDateTimeCompare - OCIDateTime CoMPare dates +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date1, date2 (IN) - dates to be compared +result (OUT) - comparison result, 0 if equal, -1 if date1 < date2, + 1 if date1 > date2 +DESCRIPTION: +The function OCIDateCompare compares two dates. It returns -1 if +date1 is smaller than date2, 0 if they are equal, and 1 if date1 is +greater than date2. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + input dates are not mutually comparable + +------------------------------OCIDateTimeConvert---------------------- +sword OCIDateTimeConvert(void *hndl, OCIError *err, OCIDateTime *indate, + OCIDateTime *outdate); +NAME: OCIDateTimeConvert - Conversion between different DATETIME types +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +indate (IN) - pointer to input date +outdate (OUT) - pointer to output datetime +DESCRIPTION: Converts one datetime type to another. The result type is + the type of the 'outdate' descriptor. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + conversion not possible. + +---------------------------- OCIDateTimeFromText----------------------- +sword OCIDateTimeFromText(void *hndl, OCIError *err, const OraText *date_str, + size_t d_str_length, const OraText *fmt, ub1 fmt_length, + const OraText *lang_name, size_t lang_length, OCIDateTime *date ); +NAME: OCIDateTimeFromText - OCIDateTime convert String FROM Date +PARAMETERS: +hndl (IN) - Session/Env handle. If Session Handle is passed, the + conversion takes place in session NLS_LANGUAGE and + session NLS_CALENDAR, otherwise the default is used. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date_str (IN) - input string to be converted to Oracle date +d_str_length (IN) - size of the input string, if the length is -1 + then 'date_str' is treated as a null terminated string +fmt (IN) - conversion format; if 'fmt' is a null pointer, then + the string is expected to be in the default format for + the datetime type. +fmt_length (IN) - length of the 'fmt' parameter +lang_name (IN) - language in which the names and abbreviations of + days and months are specified, if null i.e. (OraText *)0, + the default language of session is used, +lang_length (IN) - length of the 'lang_name' parameter +date (OUT) - given string converted to date +DESCRIPTION: + Converts the given string to Oracle datetime type set in the + OCIDateTime descriptor according to the specified format. Refer to + "TO_DATE" conversion function described in "Oracle SQL Language + Reference Manual" for a description of format. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid format + unknown language + invalid input string + +--------------------------- OCIDateTimeGetDate------------------------- +sword OCIDateTimeGetDate(void *hndl, OCIError *err, const OCIDateTime *date, + sb2 *year, ub1 *month, ub1 *day ); +NAME: OCIDateTimeGetDate - OCIDateTime Get Date (year, month, day) + portion of DATETIME. +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime +year (OUT) - year value +month (OUT) - month value +day (OUT) - day value + +--------------------------- OCIDateTimeGetTime ------------------------ +sword OCIDateTimeGetTime(void *hndl, OCIError *err, OCIDateTime *datetime, + ub1 *hour, ub1 *minute, ub1 *sec, ub4 *fsec); +NAME: OCIDateTimeGetTime - OCIDateTime Get Time (hour, min, second, + fractional second) of DATETIME. +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime +hour (OUT) - hour value +minute (OUT) - minute value +sec (OUT) - second value +fsec (OUT) - Fractional Second value + +--------------------------- OCIDateTimeGetTimeZoneOffset ---------------------- +sword OCIDateTimeGetTimeZoneOffset(void *hndl,OCIError *err,const + OCIDateTime *datetime,sb1 *hour,sb1 *minute); + +NAME: OCIDateTimeGetTimeZoneOffset - OCIDateTime Get TimeZone (hour, minute) + portion of DATETIME. +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime +hour (OUT) - TimeZone Hour value +minute (OUT) - TimeZone Minute value + +--------------------------- OCIDateTimeSysTimeStamp--------------------- +sword OCIDateTimeSysTimeStamp(void *hndl, OCIError *err, + OCIDateTime *sys_date ); + +NAME: OCIDateTimeSysTimeStamp - Returns system date/time as a TimeStamp with + timezone +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +sys_date (OUT) - Pointer to output timestamp + +DESCRIPTION: + Gets the system current date and time as a timestamp with timezone +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + + +------------------------------OCIDateTimeIntervalAdd---------------------- +sword OCIDateTimeIntervalAdd(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); +NAME: OCIDateTimeIntervalAdd - Adds an interval to datetime +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - pointer to input datetime +inter (IN) - pointer to interval +outdatetime (IN) - pointer to output datetime. The output datetime + will be of same type as input datetime +DESCRIPTION: + Adds an interval to a datetime to produce a resulting datetime +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + resulting date is before Jan 1, -4713 + resulting date is after Dec 31, 9999 + +------------------------------OCIDateTimeIntervalSub---------------------- +sword OCIDateTimeIntervalSub(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); +NAME: OCIDateTimeIntervalSub - Subtracts an interval from a datetime +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - pointer to input datetime +inter (IN) - pointer to interval +outdatetime (IN) - pointer to output datetime. The output datetime + will be of same type as input datetime +DESCRIPTION: + Subtracts an interval from a datetime and stores the result in a + datetime +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + resulting date is before Jan 1, -4713 + resulting date is after Dec 31, 9999 + +--------------------------- OCIDateTimeConstruct------------------------- +sword OCIDateTimeConstruct(void *hndl,OCIError *err,OCIDateTime *datetime, + sb2 year,ub1 month,ub1 day,ub1 hour,ub1 min,ub1 sec,ub4 fsec, + OraText *timezone,size_t timezone_length); + +NAME: OCIDateTimeConstruct - Construct an OCIDateTime. Only the relevant + fields for the OCIDateTime descriptor types are used. +PARAMETERS: + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + datetime (IN) - Pointer to OCIDateTime + year (IN) - year value + month (IN) - month value + day (IN) - day value + hour (IN) - hour value + min (IN) - minute value + sec (IN) - second value + fsec (IN) - Fractional Second value + timezone (IN) - Timezone string + timezone_length(IN) - Length of timezone string + +DESCRIPTION: + Constructs a DateTime descriptor. The type of the datetime is the + type of the OCIDateTime descriptor. Only the relevant fields based + on the type are used. For Types with timezone, the date and time + fields are assumed to be in the local time of the specified timezone. + If timezone is not specified, then session default timezone is + assumed. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR if datetime is not valid. + +------------------------------OCIDateTimeSubtract----------------------- +sword OCIDateTimeSubtract(void *hndl, OCIError *err, OCIDateTime *indate1, + OCIDateTime *indate2, OCIInterval *inter); +NAME: OCIDateTimeSubtract - subtracts two datetimes to return an interval +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +indate1(IN) - pointer to subtrahend +indate2(IN) - pointer to minuend +inter (OUT) - pointer to output interval +DESCRIPTION: + Takes two datetimes as input and stores their difference in an + interval. The type of the interval is the type of the 'inter' + descriptor. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + datetimes are not comparable. + +--------------------------- OCIDateTimeToText-------------------------- +sword OCIDateTimeToText(void *hndl, OCIError *err, const OCIDateTime *date, + const OraText *fmt, ub1 fmt_length, ub1 fsprec, + const OraText *lang_name, size_t lang_length, + ub4 *buf_size, OraText *buf ); +NAME: OCIDateTimeToText - OCIDateTime convert date TO String +PARAMETERS: +hndl (IN) - Session/Env handle. If Session Handle is passed, the + conversion takes place in session NLS_LANGUAGE and + session NLS_CALENDAR, otherwise the default is used. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date (IN) - Oracle datetime to be converted +fmt (IN) - conversion format, if null string pointer (OraText*)0, then + the date is converted to a character string in the + default format for that type. +fmt_length (IN) - length of the 'fmt' parameter +fsprec (IN) - specifies the fractional second precision in which the + fractional seconds is returned. +lang_name (IN) - specifies the language in which the names and + abbreviations of months and days are returned; + default language of session is used if 'lang_name' + is null i.e. (OraText *)0 +lang_length (IN) - length of the 'nls_params' parameter +buf_size (IN/OUT) - size of the buffer; size of the resulting string + is returned via this parameter +buf (OUT) - buffer into which the converted string is placed +DESCRIPTION: + Converts the given date to a string according to the specified format. + Refer to "TO_DATE" conversion function described in + "Oracle SQL Language Reference Manual" for a description of format + and NLS arguments. The converted null-terminated date string is + stored in the buffer 'buf'. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + invalid format + unknown language + overflow error + +----------------------------OCIDateTimeGetTimeZoneName------------------------ +sword OCIDateTimeGetTimeZoneName(void *hndl, + OCIError *err, + const OCIDateTime *datetime, + ub1 *buf, + ub4 *buflen); +NAME OCIDateTimeGetTimeZoneName - OCI DateTime Get the Time Zone Name +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to an OCIDateTime. +buf (OUT) - User allocated storage for name string. +buflen (IN/OUT) - length of buf on input, length of name on out +DESCRIPTION: + Returns either the timezone region name or the absolute hour and minute + offset. If the DateTime was created with a region id then the region + name will be returned in the buf. If the region id is zero, then the + hour and minute offset is returned as "[-]HH:MM". +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + error retrieving timezone data + invalid region + invalid LdiDateTime type + +---------------------------------OCIDateTimeToArray---------------------------- +sword OCIDateTimeToArray(void *hndl, + OCIError *err, + const OCIDateTime *datetime, + const OCIInterval *reftz, + ub1 *outarray, + ub4 *len + ub1 *fsprec); +NAME OCIDateTimeToArray - OCI DateTime convert To Array format +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime to be converted. +outarray (OUT) - Result array storage +len (OUT) - pointer to length of outarray. +fsprec (IN) - Number of fractional seconds digits. +DESCRIPTION: + Returns an array representing the input DateTime descriptor. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + error retrieving timezone data + invalid region + invalid LdiDateTime type + +--------------------------------OCIDateTimeFromArray--------------------------- +sword OCIDateTimeFromArray(void *hndl, + OCIError *err, + ub1 *inarray, + ub4 len + ub1 type + OCIDateTime *datetime, + OCIInterval *reftz, + ub1 fsprec); +NAME OCIDateTimeFromArray - OCI DateTime convert From Array format +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +inarray (IN) - Pointer to input array representtion of DateTime +len (IN) - len of inarray. +type (IN) - One of SQLT_DATE, SQLT_TIME, SQLT_TIME_TZ, SQLT_TIMESTAMP, + SQLT_TIMESTAMP_TZ, or SQLT_TIMESTAMP_LTZ. +datetime (OUT) - Pointer to the result OCIDateTime. +reftz (IN) - timezone interval used with SQLT_TIMESTAMP_LTZ. +fsprec (IN) - fractionl seconds digits of precision (0-9). +DESCRIPTION: + Returns a pointer to an OCIDateTime of type type converted from + the inarray. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + error retrieving timezone data + invalid region + invalid LdiDateTime type + +----------------------------------OCIRowidToChar----------------------------- +Name +OCIRowidToChar + +Purpose +Converts physical/logical (universal) ROWID to chracter extended (Base 64) +representation into user provided buffer outbfp of length outbflp. After +execution outbflp contains amount of bytes converted.In case of truncation +error, outbflp contains required size to make this conversion successful +and returns ORA-1405. + +Syntax +sword OCIRowidToChar( OCIRowid *rowidDesc, + OraText *outbfp, + ub2 *outbflp, + OCIError *errhp) + +Comments +After this conversion, ROWID in character format can be bound using +OCIBindByPos or OCIBindByName call and used to query a row at a +desired ROWID. + +Parameters +rowidDesc (IN) - rowid DESCriptor which is allocated from OCIDescritorAlloc + and populated by a prior SQL statement execution +outbfp (OUT) - pointer to the buffer where converted rowid in character + representation is stored after successful execution. +outbflp (IN/OUT) - pointer to output buffer length variable. + Before execution (IN mode) *outbflp contains the size of + outbfp, after execution (OUT mode) *outbflp contains amount + of bytes converted. In an event of truncation during + conversion *outbflp contains the required length to make + conversion successful. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for + diagnostic information in the event of an error. + +------------------------------OCIDefineArrayOfStruct-------------------------- + + +OCIDefineArrayOfStruct() +Name +OCI Define for Array of Structures +Purpose +This call specifies additional attributes necessary for a static array define. +Syntax +sword OCIDefineArrayOfStruct ( OCIDefine *defnp, + OCIError *errhp, + ub4 pvskip, + ub4 indskip, + ub4 rlskip, + ub4 rcskip ); +Comments +This call specifies additional attributes necessary for an array define, +used in an array of structures (multi-row, multi-column) fetch. +For more information about skip parameters, see the section "Skip Parameters" +on page 4-17. +Parameters +defnp (IN) - the handle to the define structure which was returned by a call +to OCIDefineByPos(). +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +pvskip (IN) - skip parameter for the next data value. +indskip (IN) - skip parameter for the next indicator location. +rlskip (IN) - skip parameter for the next return length value. +rcskip (IN) - skip parameter for the next return code. +Related Functions +OCIAttrGet() + + + + + +OCIDefineByPos() +Name +OCI Define By Position +Purpose +Associates an item in a select-list with the type and output data buffer. +Syntax +sb4 OCIDefineByPos ( + OCIStmt *stmtp, + OCIDefine **defnp, + OCIError *errhp, + ub4 position, + void *valuep, + sb4 value_sz, + ub2 dty, + void *indp, + ub2 *rlenp, + ub2 *rcodep, + ub4 mode ); +Comments +This call defines an output buffer which will receive data retreived from +Oracle. The define is a local step which is necessary when a SELECT statement +returns data to your OCI application. +This call also implicitly allocates the define handle for the select-list item. +Defining attributes of a column for a fetch is done in one or more calls. The +first call is to OCIDefineByPos(), which defines the minimal attributes +required to specify the fetch. +This call takes as a parameter a define handle, which must have been +previously allocated with a call to OCIHandleAlloc(). +Following the call to OCIDefineByPos() additional define calls may be +necessary for certain data types or fetch modes: +A call to OCIDefineArrayOfStruct() is necessary to set up skip parameters +for an array fetch of multiple columns. +A call to OCIDefineObject() is necessary to set up the appropriate +attributes of a named data type fetch. In this case the data buffer pointer +in ocidefn() is ignored. +Both OCIDefineArrayOfStruct() and OCIDefineObject() must be called +after ocidefn() in order to fetch multiple rows with a column of named +data types. +For a LOB define, the buffer pointer must be a lob locator of type +OCILobLocator , allocated by the OCIDescAlloc() call. LOB locators, and not +LOB values, are always returned for a LOB column. LOB values can then be +fetched using OCI LOB calls on the fetched locator. +For NCHAR (fixed and varying length), the buffer pointer must point to an +array of bytes sufficient for holding the required NCHAR characters. +Nested table columns are defined and fetched like any other named data type. +If the mode parameter is this call is set to OCI_DYNAMIC_FETCH, the client +application can fetch data dynamically at runtime. +Runtime data can be provided in one of two ways: +callbacks using a user-defined function which must be registered with a +subsequent call to OCIDefineDynamic(). When the client library needs a +buffer to return the fetched data, the callback will be invoked and the +runtime buffers provided will return a piece or the whole data. +a polling mechanism using calls supplied by the OCI. This mode is +assumed if no callbacks are defined. In this case, the fetch call returns the +OCI_NEED_DATA error code, and a piecewise polling method is used +to provide the data. +Related Functions: For more information about using the +OCI_DYNAMIC_FETCH mode, see the section "Runtime Data +Allocation and Piecewise Operations" on page 5-16 of Volume 1.. +For more information about the define step, see the section "Defining" +on page 2-30. +Parameters +stmtp (IN) - a handle to the requested SQL query operation. +defnp (IN/OUT) - a pointer to a pointer to a define handle which is implicitly +allocated by this call. This handle is used to store the define information +for this column. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +position (IN) - the position of this value in the select list. Positions are +1-based and are numbered from left to right. For example, in the SELECT +statement +SELECT empno, ssn, mgrno FROM employees; +empno is at position 1, ssn is at position 2, and mgrno is at position 3. +valuep (IN/OUT) - a pointer to a buffer or an array of buffers of the type +specified in the dty parameter. A number of buffers can be specified when +results for more than one row are desired in a single fetch call. +value_sz (IN) - the size of each valuep buffer in bytes. If the data is stored +internally in VARCHAR2 format, the number of characters desired, if different +from the buffer size in bytes, may be additionally specified by the using +OCIAttrSet(). +In an NLS conversion environment, a truncation error will be generated if the +number of bytes specified is insufficient to handle the number of characters +desired. +dty (IN) - the data type. Named data type (SQLT_NTY) and REF (SQLT_REF) +are valid only if the environment has been intialized with in object mode. +indp - pointer to an indicator variable or array. For scalar data types, +pointer to sb2 or an array of sb2s. Ignored for named data types. For named +data types, a pointer to a named data type indicator structure or an array of +named data type indicator structures is associated by a subsequent +OCIDefineObject() call. +See the section "Indicator Variables" on page 2-43 for more information about +indicator variables. +rlenp (IN/OUT) - pointer to array of length of data fetched. Each element in +rlenp is the length of the data in the corresponding element in the row after +the fetch. +rcodep (OUT) - pointer to array of column-level return codes +mode (IN) - the valid modes are: +OCI_DEFAULT. This is the default mode. +OCI_DYNAMIC_FETCH. For applications requiring dynamically +allocated data at the time of fetch, this mode must be used. The user may +additionally call OCIDefineDynamic() to set up a callback function that +will be invoked to receive the dynamically allocated buffers and to set +up the memory allocate/free callbacks and the context for the callbacks. +valuep and value_sz are ignored in this mode. +Related Functions +OCIDefineArrayOfStruct(), OCIDefineDynamic(), OCIDefineObject() + + + + +OCIDefineDynamic() +Name +OCI Define Dynamic Fetch Attributes +Purpose +This call is used to set the additional attributes required if the +OCI_DYNAMIC_FETCH mode was selected in OCIDefineByPos(). +Syntax +sword OCIDefineDynamic( OCIDefine *defnp, + OCIError *errhp, + void *octxp, + OCICallbackDefine (ocbfp)( + void *octxp, + OCIDefine *defnp, + ub4 iter, + void **bufpp, + ub4 **alenpp, + ub1 *piecep, + void **indpp, + ub2 **rcodep) ); +Comments +This call is used to set the additional attributes required if the +OCI_DYNAMIC_FETCH mode has been selected in a call to +OCIDefineByPos(). +When the OCI_DYNAMIC_FETCH mode is selected, buffers will be +dynamically allocated for REF, and named data type, values to receive the +data. The pointers to these buffers will be returned. +If OCI_DYNAMIC_FETCH mode was selected, and the call to +OCIDefineDynamic() is skipped, then the application can fetch data piecewise +using OCI calls. +For more information about OCI_DYNAMIC_FETCH mode, see the section +"Runtime Data Allocation and Piecewise Operations" on page 5-16. +Parameters +defnp (IN/OUT) - the handle to a define structure returned by a call to +OCIDefineByPos(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +octxp (IN) - points to a context for the callback function. +ocbfp (IN) - points to a callback function. This is invoked at runtime to get +a pointer to the buffer into which the fetched data or a piece of it will be +retreived. The callback also specifies the indicator, the return code and the +lengths of the data piece and indicator. The callback has the following +parameters: +octxp (IN) - a context pointer passed as an argument to all the callback +functions. +defnp (IN) - the define handle. +iter (IN) - which row of this current fetch. +bufpp (OUT) - returns a pointer to a buffer to store the column value, ie. +*bufp points to some appropriate storage for the column value. +alenpp (OUT) - returns a pointer to the length of the buffer. *alenpp +contains the size of the buffer after return from callback. Gets set to +actual data size after fetch. +piecep (IN/OUT) - returns a piece value, as follows: +The IN value can be OCI_ONE_PIECE, OCI_FIRST_PIECE or +OCI_NEXT_PIECE. +The OUT value can be OCI_ONE_PIECE if the IN value was +OCI_ONE_PIECE. +The OUT value can be OCI_ONE_PIECE or OCI_FIRST_PIECE if +the IN value was OCI_FIRST_PIECE. +The OUT value can only be OCI_NEXT_PIECE or +OCI_LAST_PIECE if the IN value was OCI_NEXT_PIECE. +indpp (IN) - indicator variable pointer +rcodep (IN) - return code variable pointer +Related Functions +OCIAttrGet() +OCIDefineObject() + + + + +OCIDefineObject() +Name +OCI Define Named Data Type attributes +Purpose +Sets up additional attributes necessary for a Named Data Type define. +Syntax +sword OCIDefineObject ( OCIDefine *defnp, + OCIError *errhp, + const OCIType *type, + void **pgvpp, + ub4 *pvszsp, + void **indpp, + ub4 *indszp ); +Comments +This call sets up additional attributes necessary for a Named Data Type define. +An error will be returned if this function is called when the OCI environment +has been initialized in non-Object mode. +This call takes as a paramter a type descriptor object (TDO) of datatype +OCIType for the named data type being defined. The TDO can be retrieved +with a call to OCITypeByName(). +See the description of OCIInitialize() on page 13 - 43 for more information +about initializing the OCI process environment. +Parameters +defnp (IN/OUT) - a define handle previously allocated in a call to +OCIDefineByPos(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +type (IN, optional) - points to the Type Descriptor Object (TDO) which +describes the type of the program variable. Only used for program variables +of type SQLT_NTY. This parameter is optional, and may be passed as NULL +if it is not being used. +pgvpp (IN/OUT) - points to a pointer to a program variable buffer. For an +array, pgvpp points to an array of pointers. Memory for the fetched named data +type instance(s) is dynamically allocated in the object cache. At the end of +the fetch when all the values have been received, pgvpp points to the +pointer(s) to these newly allocated named data type instance(s). The +application must call OCIObjectMarkDel() to deallocate the named data type +instance(s) when they are no longer needed. +pvszsp (IN/OUT) - points to the size of the program variable. For an array, it +is an array of ub4s. On return points to the size(s) of unpickled fetched +values. +indpp (IN/OUT) - points to a pointer to the program variable buffer +containing the parallel indicator structure. For an array, points to an array +of pointers. Memory is allocated to store the indicator structures in the +object cache. At the end of the fetch when all values have been received, +indpp points to the pointer(s) to these newly allocated indicator structure(s). +indszp (IN/OUT) - points to the size(s) of the indicator structure program +variable. For an array, it is an array of ub4s. On return points to the size(s) +of the unpickled fetched indicator values. +Related Functions +OCIAttrGet() + + + +OCIDescAlloc() +Name +OCI Get DESCriptor or lob locator +Purpose +Allocates storage to hold certain data types. The descriptors can be used as +bind or define variables. +Syntax +sword OCIDescAlloc ( const void *parenth, + void **descpp, + ub4 type, + size_t xtramem_sz, + void **usrmempp); +Comments +Returns a pointer to an allocated and initialized structure, corresponding to +the type specified in type. A non-NULL descriptor or LOB locator is returned +on success. No diagnostics are available on error. +This call returns OCI_SUCCESS if successful, or OCI_INVALID_HANDLE if +an out-of-memory error occurs. +Parameters +parenth (IN) - an environment handle. +descpp (OUT) - returns a descriptor or LOB locator of desired type. +type (IN) - specifies the type of descriptor or LOB locator to be allocated. +The specific types are: +OCI_DTYPE_SNAP - specifies generation of snapshot descriptor of C +type - OCISnapshot +OCI_DTYPE_LOB - specifies generation of a LOB data type locator of C +type - OCILobLocator +OCI_DTYPE_RSET - specifies generation of a descriptor of C type +OCIResult that references a result set (a number of rows as a result of a +query). This descriptor is bound to a bind variable of data type +SQLT_RSET (result set). The descriptor has to be converted into a +statement handle using a function - OCIResultSetToStmt() - which can +then be passed to OCIDefineByPos() and OCIStmtFetch() to retrieve the +rows of the result set. +OCI_DTYPE_ROWID - specifies generation of a ROWID descriptor of C +type OCIRowid. +OCI_DTYPE_COMPLEXOBJECTCOMP - specifies generation of a +complex object retrieval descriptor of C type +OCIComplexObjectComp. +xtramemsz (IN) - specifies an amount of user memory to be allocated for use +by the application. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. +Related Functions +OCIDescFree() + + + + +OCIDescFree() +Name +OCI Free DESCriptor +Purpose +Deallocates a previously allocated descriptor. +Syntax +sword OCIDescFree ( void *descp, + ub4 type); +Comments +This call frees up storage associated with the descriptor, corresponding to the +type specified in type. Returns OCI_SUCCESS or OCI_INVALID_HANDLE. +All descriptors must be explicitly deallocated. OCI will not deallocate a +descriptor if the environment handle is deallocated. +Parameters +descp (IN) - an allocated descriptor. +type (IN) - specifies the type of storage to be freed. The specific types are: +OCI_DTYPE_SNAP - snapshot descriptor +OCI_DTYPE_LOB - a LOB data type descriptor +OCI_DTYPE_RSET - a descriptor that references a result set (a number +of rows as a result of a query). +OCI_DTYPE_ROWID - a ROWID descriptor +OCI_DTYPE_COMPLEXOBJECTCOMP - a complex object retrieval +descriptor +Related Functions +OCIDescAlloc() + + + +OCIDescribeAny() +Name +OCI DeSCribe Any +Purpose +Describes existing schema objects. +Syntax +sword OCIDescribeAny ( OCISvcCtx *svchp, + OCIError *errhp, + void *objptr, + ub4 objnm_len, + ub1 objptr_typ, + ub1 info_level, + ub1 objtype, + OCIDesc *dschp ); +Comments +This is a generic describe call that describes existing schema objects: tables, +views, synonyms, procedures, functions, packages, sequences, and types. As a +result of this call, the describe handle is populated with the object-specific +attributes which can be obtained through an OCIAttrGet() call. +An OCIParamGet() on the describe handle returns a parameter descriptor for a +specified position. Parameter positions begin with 1. Calling OCIAttrGet() on +the parameter descriptor returns the specific attributes of a stored procedure +or function parameter or a table column descriptor as the case may be. +These subsequent calls do not need an extra round trip to the server because +the entire schema object description cached on the client side by +OCIDescribeAny(). Calling OCIAttrGet() on the describe handle can also return +the total number of positions. +See the section "Describing" on page 2-33 for more information about describe +operations. +Parameters +TO BE UPDATED +svchp (IN/OUT) - a service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +objptr (IN) - the name of the object (a null-terminated string) to be +described. Only procedure or function names are valid when connected to an +Oracle7 Server. +objptr_len (IN) - the length of the string. Must be non-zero. +objptr_typ (IN) - Must be OCI_OTYPE_NAME, OCI_OTYPE_REF, or OCI_OTYPE_PTR. +info_level (IN) - reserved for future extensions. Pass OCI_DEFAULT. +objtype (IN/OUT) - object type. +dschp (IN/OUT) - a describe handle that is populated with describe +information about the object after the call. +Related Functions +OCIAttrGet() + + + +OCIEnvCreate() +Name +OCI ENVironment CREATE +Purpose +This function creates and initializes an environment for the rest of +the OCI functions to work under. This call is a replacement for both +the OCIInitialize and OCIEnvInit calls. +Syntax +sword OCIEnvCreate ( OCIEnv **envhpp, + ub4 mode, + const void *ctxp, + const void *(*malocfp) + (void *ctxp, + size_t size), + const void *(*ralocfp) + (void *ctxp, + void *memptr, + size_t newsize), + const void (*mfreefp) + ( void *ctxp, + void *memptr)) + size_t xtramemsz, + void **usrmempp ); + +Comments +This call creates an environment for all the OCI calls using the modes +specified by the user. This call can be used instead of the two calls +OCIInitialize and OCIEnvInit. This function returns an environment handle +which is then used by the remaining OCI functions. There can be multiple +environments in OCI each with its own environment modes. This function +also performs any process level initialization if required by any mode. +For example if the user wants to initialize an environment as OCI_THREADED, +then all libraries that are used by OCI are also initialized in the +threaded mode. + +This call should be invoked before anny other OCI call and should be used +instead of the OCIInitialize and OCIEnvInit calls. This is the recommended +call, although OCIInitialize and OCIEnvInit calls will still be supported +for backward compatibility. + +envpp (OUT) - a pointer to a handle to the environment. +mode (IN) - specifies initialization of the mode. The valid modes are: +OCI_DEFAULT - default mode. +OCI_THREADED - threaded environment. In this mode, internal data +structures are protected from concurrent accesses by multiple threads. +OCI_OBJECT - will use navigational object interface. +ctxp (IN) - user defined context for the memory call back routines. +malocfp (IN) - user-defined memory allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory allocation function. +size - size of memory to be allocated by the user-defined memory +allocation function +ralocfp (IN) - user-defined memory re-allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory reallocation +function. +memp - pointer to memory block +newsize - new size of memory to be allocated +mfreefp (IN) - user-defined memory free function. If mode is +OCI_THREADED, this memory free routine must be thread safe. +ctxp - context pointer for the user-defined memory free function. +memptr - pointer to memory to be freed +xtramemsz (IN) - specifies the amount of user memory to be allocated. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. + +Example + +Related Functions +OCIInitialize, OCIEnvInit + +OCIEnvNlsCreate() +Name +OCI ENVironment CREATE with NLS info +Purpose +This function does almost everything OCIEnvCreate does, plus enabling setting +of charset and ncharset programmatically, except OCI_UTF16 mode. +Syntax +sword OCIEnvNlsCreate(OCIEnv **envhpp, + ub4 mode, + void *ctxp, + void *(*malocfp) + (void *ctxp, + size_t size), + void *(*ralocfp) + (void *ctxp, + void *memptr, + size_t newsize), + void (*mfreefp) + (void *ctxp, + void *memptr), + size_t xtramemsz, + void **usrmempp, + ub2 charset, + ub2 ncharset) +Comments +The charset and ncharset must be both zero or non-zero. +The parameters have the same meaning as the ones in OCIEnvCreate(). +When charset or ncharset is non-zero, the corresponding character set will +be used to replace the ones specified in NLS_LANG or NLS_NCHAR. Moreover, +OCI_UTF16ID is allowed to be set as charset and ncharset. +On the other hand, OCI_UTF16 mode is deprecated with this function. +Applications can achieve the same effects by setting +both charset and ncharset as OCI_UTF16ID. + + +OCIEnvInit() +Name +OCI INITialize environment +Purpose +This call initializes the OCI environment handle. +Syntax +sword OCIEnvInit ( OCIEnv **envp, + ub4 mode, + size_t xtramemsz, + void **usrmempp ); +Comments +Initializes the OCI environment handle. No changes are done on an initialized +handle. If OCI_ERROR or OCI_SUCCESS_WITH_INFO is returned, the +environment handle can be used to obtain ORACLE specific errors and +diagnostics. +This call is processed locally, without a server round-trip. +Parameters +envpp (OUT) - a pointer to a handle to the environment. +mode (IN) - specifies initialization of an environment mode. The only valid +mode is OCI_DEFAULT for default mode +xtramemsz (IN) - specifies the amount of user memory to be allocated. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. +Example +See the description of OCISessionBegin() on page 13-84 for an example showing +the use of OCIEnvInit(). +Related Functions + + + + +OCIErrorGet() +Name +OCI Get Diagnostic Record +Purpose +Returns an error message in the buffer provided and an ORACLE error. +Syntax +sword OCIErrorGet ( void *hndlp, + ub4 recordno, + OraText *sqlstate, + ub4 *errcodep, + OraText *bufp, + ub4 bufsiz, + ub4 type ); +Comments +Returns an error message in the buffer provided and an ORACLE error. +Currently does not support SQL state. This call can be called a multiple +number of times if there are more than one diagnostic record for an error. +The error handle is originally allocated with a call to OCIHandleAlloc(). +Parameters +hndlp (IN) - the error handle, in most cases, or the environment handle (for +errors on OCIEnvInit(), OCIHandleAlloc()). +recordno (IN) - indicates the status record from which the application seeks +info. Starts from 1. +sqlstate (OUT) - Not supported in Version 8.0. +errcodep (OUT) - an ORACLE Error is returned. +bufp (OUT) - the error message text is returned. +bufsiz (IN) - the size of the buffer provide to get the error message. +type (IN) - the type of the handle. +Related Functions +OCIHandleAlloc() + +OCIExtractInit +Name +OCI Extract Initialize +Purpose +This function initializes the parameter manager. +Syntax +sword OCIExtractInit(void *hndl, OCIError *err); +Comments +It must be called before calling any other parameter manager routine. The NLS +information is stored inside the parameter manager context and used in +subsequent calls to OCIExtract routines. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +Related Functions +OCIExtractTerm() + +OCIExtractTerm +Name +OCI Extract Terminate +Purpose +This function releases all dynamically allocated storage and may perform +other internal bookkeeping functions. +Syntax +sword OCIExtractTerm(void *hndl, OCIError *err); +Comments +It must be called when the parameter manager is no longer being used. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +Related Functions +OCIExtractInit() + +OCIExtractReset +Name +OCI Extract Reset +Purpose +The memory currently used for parameter storage, key definition storage, and +parameter value lists is freed and the structure is reinitialized. +Syntax +sword OCIExtractReset(void *hndl, OCIError *err); +Comments +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +Related Functions + +OCIExtractSetNumKeys +Name +OCI Extract Set Number of Keys +Purpose +Informs the parameter manager of the number of keys that will be registered. +Syntax +sword OCIExtractSetNumKeys(void *hndl, OCIError *err, uword numkeys); +Comments +This routine must be called prior to the first call of OCIExtractSetKey(). +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +numkeys (IN) - The number of keys that will be registered with + OCIExtractSetKey(). +Related Functions +OCIExtractSetKey() + +OCIExtractSetKey +Name +OCI Extract Set Key definition +Purpose +Registers information about a key with the parameter manager. +Syntax +sword OCIExtractSetKey(void *hndl, OCIError *err, const OraText *name, + ub1 type, ub4 flag, const void *defval, + const sb4 *intrange, const OraText *const *strlist); +Comments +This routine must be called after calling OCIExtractSetKey() and before +calling OCIExtractFromFile() or OCIExtractFromStr(). +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +name (IN) - The name of the key. +type (IN) - The type of the key (OCI_EXTRACT_TYPE_INTEGER, + OCI_EXTRACT_TYPE_OCINUM, OCI_EXTRACT_TYPE_STRING, or + OCI_EXTRACT_TYPE_BOOLEAN). +flag (IN) - Set to OCI_EXTRACT_MULTIPLE if the key can take multiple values + or 0 otherwise. +defval (IN) - Set to the default value for the key. May be NULL if there is + no default. A string default must be a (text*) type, an + integer default must be an (sb4*) type, and a boolean default + must be a (ub1*) type. +intrange (IN) - Starting and ending values for the allowable range of integer + values. May be NULL if the key is not an integer type or if + all integer values are acceptable. +strlist (IN) - List of all acceptable text strings for the key. May be NULL + if the key is not a string type or if all text values are + acceptable. +Related Functions +OCIExtractSetNumKeys() + +OCIExtractFromFile +Name +OCI Extract parameters From File +Purpose +The keys and their values in the given file are processed. +Syntax +sword OCIExtractFromFile(void *hndl, OCIError *err, ub4 flag, + OraText *filename); +Comments +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +flag (IN) - Zero or has one or more of the following bits set: + OCI_EXTRACT_CASE_SENSITIVE, OCI_EXTRACT_UNIQUE_ABBREVS, or + OCI_EXTRACT_APPEND_VALUES. +filename (IN) - Null-terminated filename string. +Related Functions + +OCIExtractFromStr +Name +OCI Extract parameters From String +Purpose +The keys and their values in the given string are processed. +Syntax +sword OCIExtractFromStr(void *hndl, OCIError *err, ub4 flag, OraText *input); +Comments +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +flag (IN) - Zero or has one or more of the following bits set: + OCI_EXTRACT_CASE_SENSITIVE, OCI_EXTRACT_UNIQUE_ABBREVS, or + OCI_EXTRACT_APPEND_VALUES. +input (IN) - Null-terminated input string. +Related Functions + +OCIExtractToInt +Name +OCI Extract To Integer +Purpose +Gets the integer value for the specified key. +Syntax +sword OCIExtractToInt(void *hndl, OCIError *err, OraText *keyname, + uword valno, sb4 *retval); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual integer value. +Related Functions + +OCIExtractToBool +Name +OCI Extract To Boolean +Purpose +Gets the boolean value for the specified key. +Syntax +sword OCIExtractToBool(void *hndl, OCIError *err, OraText *keyname, + uword valno, ub1 *retval); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual boolean value. +Related Functions + +OCIExtractToStr +Name +OCI Extract To String +Purpose +Gets the string value for the specified key. +Syntax +sword OCIExtractToStr(void *hndl, OCIError *err, OraText *keyname, + uword valno, OraText *retval, uword buflen); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual null-terminated string value. +buflen (IN) - The length of the buffer for retval. +Related Functions + +Note: The following OCIExtract functions are unavailable in this release + +OCIExtractToOCINum +Name +OCI Extract To OCI Number +Purpose +Gets the OCINumber value for the specified key. +Syntax +sword OCIExtractToOCINum(void *hndl, OCIError *err, OraText *keyname, + uword valno, OCINumber *retval); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual OCINumber value. +Related Functions + +OCIExtractToList +Name +OCI Extract To parameter List +Purpose +Generates a list of parameters from the parameter structures that are stored +in memory. +Syntax +sword OCIExtractToList(void *hndl, OCIError *err, uword *numkeys); +Comments +Must be called before OCIExtractValues() is called. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +numkeys (OUT) - Number of distinct keys stored in memory. +Related Functions +OCIExtractFromList() + +OCIExtractFromList +Name +OCI Extract From parameter List +Purpose +Generates a list of values for the a parameter in the parameter list. +Syntax +sword OCIExtractFromList(void *hndl, OCIError *err, uword index, + OraText *name, ub1 *type, uword *numvals, + void ***values); +Comments +Parameters are specified by an index. OCIExtractToList() must be called prior +to calling this routine to generate the parameter list from the parameter +structures that are stored in memory. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +name (OUT) - Name of the key for the current parameter. +type (OUT) - Type of the current parameter (OCI_EXTRACT_TYPE_STRING, + OCI_EXTRACT_TYPE_INTEGER, OCI_EXTRACT_TYPE_OCINUM, or + OCI_EXTRACT_TYPE_BOOLEAN) +numvals (OUT) - Number of values for this parameter. +values (OUT) - The values for this parameter. +Related Functions +OCIExtractToList() + + +************************ OCIFileClose() *********************************** + +Name + OCIFileClose - Oracle Call Interface FILE i/o CLOSE + +Purpose + Close a previously opened file. + +Syntax + sword OCIFileClose ( void *hndl, + OCIError *err, + OCIFileObject *filep ) + +Comments + This function will close a previously opened file. If the function succeeds + then OCI_SUCCESS will be returned, else OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle + filep (IN) - the OCIFile file object + +Related Functions + OCIFileOpen. + + + +********************* OCIFileExists() ************************************** + +Name + OCIFileExists - Oracle Call Interface FILE i/o EXIST + +Purpose + Check to see if the file exists. + +Syntax + sword OCIFileExists ( void *hndl, + OCIError *err, + OraText *filename, + OraText *path, + ub1 *flag ) + +Comments + This function will set the flag to TRUE if the file exists else it will + be set to FALSE. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl(IN) - OCI environment or session handle + err(OUT) - OCI error handle + filename(IN) - filename + path(IN) - path of the file + flag(OUT) - whether the file exists or not + +Related Functions. + None. + + + **************************** OCIFileFlush() ****************************** + + +Name + OCIFileFlush - Oracle Call Interface File i/o FLUSH + +Purpose + Flush the buffers associated with the file to the disk. + +Syntax + sword OCIFileFlush ( void *hndl, + OCIError *err, + OCIFileObject *filep ) + +Comments + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle + filep (IN) - the OCIFile file object + +Related Functions + OCIFileOpen, OCIFileWrite + + + + *************************** OCIFileGetLength() **************************** + +Name + OCIFileGetLength - Oracle Call Interface FILE i/o GET file LENGTH + +Purpose + Get the length of a file. + +Syntax + OCIFileGetLength(void *hndl, + OCIError *err, + OraText *filename, + OraText *path, + ubig_ora *lenp ) + +Comments + The length of the file will be returned in lenp. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filename (IN) - file name. + path (IN) - path of the file. + lenp (OUT) - On output, it is the length of the file in bytes. + is the number of bytes in the file. + +Related Functions + None. + + + +******************************** OCIFileInit() ***************************** + +Name + OCIFileInit - Oracle Call Interface FILE i/o INITialize + +Purpose + Initialize the OCI File I/O package and create the OCIFile context. + +Syntax + sword OCIFileInit ( void *hndl, + OCIError *err) + +Comments + This function should be called before any of the OCIFile functions are + used. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl(IN) - OCI environment or session handle. + err(OUT) - OCI error structure. + +Related Functions + OCIFileTerm + + + +********************************* OCIFileOpen() ***************************** + +Name + OCIFileOpen - Oracle Call Interface File i/o OPEN + +Purpose + Open a file. + +Syntax + sword OCIFileOpen ( void *hndl, + OCIError *err, + OCIFileObject **filep, + OraText *filename, + OraText *path, + ub4 mode, + ub4 create, + ub4 type ) + +Comments + OCIFileOpen returns a handle to the open file in filep if the file is + successfully opened. + If one wants to use the standard file objects (stdin, stdout & stderr) + then OCIFileOpen whould be called with the type filed containing the + appropriate type (see the parameter type). If any of the standard files + are specified then filename, path, mode and create are ignored. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (OUT) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (OUT) - the file object to be returned. + filename (IN) - file name (NULL terminated string). + path (IN) - path of the file (NULL terminated string). + mode - mode in which to open the file (valid modes are OCI_FILE_READONLY, + OCI_FILE_WRITEONLY, OCI_FILE_READ_WRITE). + create - should the file be created if it does not exist. Valid values + are: + OCI_FILE_TRUNCATE - create a file regardless of whether or not it exists. + If the file already exists overwrite it. + OCI_FILE_EXIST - open it if it exists, else fail. + OCI_FILE_EXCL - fail if the file exists, else create. + OCI_FILE_CREATE - open the file if it exists, and create it if it doesn't. + OCI_FILE_APPEND - set the file pointer to the end of the file prior to + writing(this flag can be OR'ed with OCI_FILE_EXIST or + OCI_FILE_CREATE). +type - file type. Valid values are OCI_FILE_TEXT, OCI_FILE_BIN, + OCI_FILE_STDIN, OCI_FILE_STDOUT and OCI_FILE_STDERR. + If any of the standard files are specified then filename, path, mode + and create are ignored. + +Related Functions. + OCIFileClose + + + +************************** OCIFileRead() ************************************ + +Name + OCIFileRead - Oracle Call Interface FILE i/o READ + +Purpose + Read from a file into a buffer. + +Syntax + sword OCIFileRead ( void *hndl, + OCIError *err, + OCIFileObject *filep, + void *bufp, + ub4 bufl, + ub4 *bytesread ) + +Comments + Upto bufl bytes from the file will be read into bufp. The user should + allocate memory for the buffer. + The number of bytes read would be in bytesread. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (IN/OUT) - a File Object that uniquely references the file. + bufp (IN) - the pointer to a buffer into which the data will be read. The + length of the allocated memory is assumed to be bufl. + bufl - the length of the buffer in bytes. + bytesread (OUT) - the number of bytes read. + +Related Functions + OCIFileOpen, OCIFileSeek, OCIFileWrite + + + +****************************** OCIFileSeek() ****************************** + +Name + OCIFileSeek - Oracle Call Interface FILE i/o SEEK + +Purpose + Perfom a seek to a byte position. + +Syntax + sword OCIFileSeek ( void *hndl, + OCIError *err, + OCIFileObject *filep, + uword origin, + ubig_ora offset, + sb1 dir) + +Comments + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (IN/OUT) - a file handle that uniquely references the file. + origin - The starting point we want to seek from. NOTE: The starting + point may be OCI_FILE_SEEK_BEGINNING (beginning), OCI_FILE_SEEK_CURRENT + (current position), or OCI_FILE_SEEK_END (end of file). + offset - The number of bytes from the origin we want to start reading from. + dir - The direction we want to go from the origin. NOTE: The direction + can be either OCI_FILE_FORWARD or OCI_FILE_BACKWARD. + +Related Function + OCIFileOpen, OCIFileRead, OCIFileWrite + + + +*************************** OCIFileTerm() ********************************** + +Name + OCIFileTerm - Oracle Call Interface FILE i/o TERMinate + +Purpose + Terminate the OCI File I/O package and destroy the OCI File context. + +Syntax + sword OCIFileTerm ( void *hndl, + OCIError *err ) + +Comments + After this function has been called no OCIFile function should be used. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl(IN) - OCI environment or session handle. + err(OUT) - OCI error structure. + +Related Functions + OCIFileInit + + +********************************* OCIFileWrite() **************************** + +Name + OCIFileWrite - Oracle Call Interface FILE i/o WRITE + +Purpose + Write data from buffer into a file. + +Syntax + sword OCIFileWrite ( void *hndl, + OCIError *err, + OCIFileObject *filep, + void *bufp, + ub4 buflen + ub4 *byteswritten ) + +Comments + The number of bytes written will be in *byteswritten. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (IN/OUT) - a file handle that uniquely references the file. + bufp (IN) - the pointer to a buffer from which the data will be written. + The length of the allocated memory is assumed to be the value passed + in bufl. + bufl - the length of the buffer in bytes. + byteswritten (OUT) - the number of bytes written. + +Related Functions + OCIFileOpen, OCIFileSeek, OCIFileRead + + + + + +OCIHandleAlloc() +Name +OCI Get HaNDLe +Purpose +This call returns a pointer to an allocated and initialized handle. +Syntax +sword OCIHandleAlloc ( const void *parenth, + void **hndlpp, + ub4 type, + size_t xtramem_sz, + void **usrmempp); +Comments +Returns a pointer to an allocated and initialized structure, corresponding to +the type specified in type. A non-NULL handle is returned on success. Bind +handle and define handles are allocated with respect to a statement handle. All +other handles are allocated with respect to an environment handle which is +passed in as a parent handle. +No diagnostics are available on error. This call returns OCI_SUCCESS if +successful, or OCI_INVALID_HANDLE if an out-of-memory error occurs. +Handles must be allocated using OCIHandleAlloc() before they can be passed +into an OCI call. +Parameters +parenth (IN) - an environment or a statement handle. +hndlpp (OUT) - returns a handle to a handle type. +type (IN) - specifies the type of handle to be allocated. The specific types +are: +OCI_HTYPE_ERROR - specifies generation of an error report handle of +C type OCIError +OCI_HTYPE_SVCCTX - specifies generation of a service context handle +of C type OCISvcCtx +OCI_HTYPE_STMT - specifies generation of a statement (application +request) handle of C type OCIStmt +OCI_HTYPE_BIND - specifies generation of a bind information handle +of C type OCIBind +OCI_HTYPE_DEFINE - specifies generation of a column definition +handle of C type OCIDefine +OCI_HTYPE_DESCRIBE - specifies generation of a select list +description handle of C type OCIDesc +OCI_HTYPE_SERVER - specifies generation of a server context handle +of C type OCIServer +OCI_HTYPE_SESSION - specifies generation of an authentication +context handle of C type OCISession +OCI_HTYPE_TRANS - specifies generation of a transaction context +handle of C type OCITrans +OCI_HTYPE_COMPLEXOBJECT - specifies generation of a complex +object retrieval handle of C type OCIComplexObject +OCI_HTYPE_SECURITY - specifies generation of a security handle of C +type OCISecurity +xtramem_sz (IN) - specifies an amount of user memory to be allocated. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. +Related Functions +OCIHandleFree() + + + +OCIHandleFree() +Name +OCI Free HaNDLe +Purpose +This call explicitly deallocates a handle. +Syntax +sword OCIHandleFree ( void *hndlp, + ub4 type); +Comments +This call frees up storage associated with a handle, corresponding to the type +specified in the type parameter. +This call returns either OCI_SUCCESS or OCI_INVALID_HANDLE. +All handles must be explicitly deallocated. OCI will not deallocate a child +handle if the parent is deallocated. +Parameters +hndlp (IN) - an opaque pointer to some storage. +type (IN) - specifies the type of storage to be allocated. The specific types +are: +OCI_HTYPE_ENV - an environment handle +OCI_HTYPE_ERROR - an error report handle +OCI_HTYPE_SVCCTX - a service context handle +OCI_HTYPE_STMT - a statement (application request) handle +OCI_HTYPE_BIND - a bind information handle +OCI_HTYPE_DEFINE - a column definition handle +OCI_HTYPE_DESCRIBE - a select list description handle +OCI_HTYPE_SERVER - a server handle +OCI_HTYPE_SESSION - a user authentication handle +OCI_HTYPE_TRANS - a transaction handle +OCI_HTYPE_COMPLEXOBJECT - a complex object retrieval handle +OCI_HTYPE_SECURITY - a security handle +Related Functions +OCIHandleAlloc() + + + + +OCIInitialize() +Name +OCI Process Initialize +Purpose +Initializes the OCI process environment. +Syntax +sword OCIInitialize ( ub4 mode, + const void *ctxp, + const void *(*malocfp) + ( void *ctxp, + size_t size ), + const void *(*ralocfp) + ( void *ctxp, + void *memp, + size_t newsize ), + const void (*mfreefp) + ( void *ctxp, + void *memptr )); +Comments +This call initializes the OCI process environment. +OCIInitialize() must be invoked before any other OCI call. +Parameters +mode (IN) - specifies initialization of the mode. The valid modes are: +OCI_DEFAULT - default mode. +OCI_THREADED - threaded environment. In this mode, internal data +structures are protected from concurrent accesses by multiple threads. +OCI_OBJECT - will use navigational object interface. +ctxp (IN) - user defined context for the memory call back routines. +malocfp (IN) - user-defined memory allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory allocation function. +size - size of memory to be allocated by the user-defined memory +allocation function +ralocfp (IN) - user-defined memory re-allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory reallocation +function. +memp - pointer to memory block +newsize - new size of memory to be allocated +mfreefp (IN) - user-defined memory free function. If mode is +OCI_THREADED, this memory free routine must be thread safe. +ctxp - context pointer for the user-defined memory free function. +memptr - pointer to memory to be freed +Example +See the description of OCIStmtPrepare() on page 13-96 for an example showing +the use of OCIInitialize(). +Related Functions + +-------------------------------OCITerminate------------------------------------ + +OCITerminate() +Name +OCI process Terminate +Purpose +Do cleanup before process termination +Syntax +sword OCITerminate (ub4 mode); + +Comments +This call performs OCI related clean up before the OCI process terminates. +If the process is running in shared mode then the OCI process is disconnected +from the shared memory subsystem. + +OCITerminate() should be the last OCI call in any process. + +Parameters +mode (IN) - specifies different termination modes. + +OCI_DEFAULT - default mode. + +Example + +Related Functions +OCIInitialize() + +------------------------ OCIAppCtxSet-------------------------------------- +Name +OCI Application context Set +Purpose +Set an attribute and its value for a particular application context + namespace +Syntax + (sword) OCIAppCtxSet((void *) sesshndl, (void *)nsptr,(ub4) nsptrlen, + (void *)attrptr, (ub4) attrptrlen, (void *)valueptr, + (ub4) valueptrlen, errhp, (ub4)mode); + +Comments +Please note that the information set on the session handle is sent to the +server during the next OCIStatementExecute or OCISessionBegin. + +This information is cleared from the session handle, once the information + has been sent over to the server,and should be setup again if needed. + +Parameters + sesshndl (IN/OUT) - Pointer to a session handle + nsptr (IN) - Pointer to namespace string + nsptrlen (IN) - length of the nsptr + attrptr (IN) - Pointer to attribute string + attrptrlen (IN) - length of the attrptr + valueptr (IN) - Pointer to value string + valueptrlen(IN) - length of the valueptr + errhp (OUT) - Error from the API + mode (IN) - mode of operation (OCI_DEFAULT) + +Returns + error if any +Example + +Related Functions + OCIAppCtxClearAll + + +------------------------ OCIAppCtxClearAll--------------------------------- +Name + OCI Application Context Clear all attributes in a namespace +Purpose + To clear the values all attributes in a namespace +Syntax + (sword) OCIAppCtxClearAll((void *) sesshndl, (void *)nsptr, (ub4) nsptrlen, + (OCIError *)errhp, (ub4)mode); + +Comments +This will clean up the context information on the server side during the +next piggy-back to the server. + +Parameters + sesshndl (IN/OUT) - Pointer to a session handle + nsptr (IN) - Pointer to namespace string where the values of all + attributes are cleared + nsptrlen (IN) - length of the nsptr + errhp (OUT) - Error from the API + mode (IN) - mode of operation (OCI_DEFAULT) +Example + +Returns + error if any + +Related Functions + OCIAppCtxSet +---------------------- OCIIntervalAssign --------------------------------- +sword OCIIntervalAssign(void *hndl, OCIError *err, + const OCIInterval *inpinter, OCIInterval *outinter ); + + DESCRIPTION + Copies one interval to another to create a replica + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inpinter - Input Interval + (OUT) outinter - Output Interval + RETURNS + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_SUCCESS otherwise + + ---------------------- OCIIntervalCheck ------------------------------------ +sword OCIIntervalCheck(void *hndl, OCIError *err, const OCIInterval *interval, + ub4 *valid ); + + DESCRIPTION + Checks the validity of an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) interval - Interval to be checked + (OUT) valid - Zero if the interval is valid, else returns an Ored + combination of the following codes. + + Macro name Bit number Error + ---------- ---------- ----- + OCI_INTER_INVALID_DAY 0x1 Bad day + OCI_INTER_DAY_BELOW_VALID 0x2 Bad DAy Low/high bit (1=low) + OCI_INTER_INVALID_MONTH 0x4 Bad MOnth + OCI_INTER_MONTH_BELOW_VALID 0x8 Bad MOnth Low/high bit (1=low) + OCI_INTER_INVALID_YEAR 0x10 Bad YeaR + OCI_INTER_YEAR_BELOW_VALID 0x20 Bad YeaR Low/high bit (1=low) + OCI_INTER_INVALID_HOUR 0x40 Bad HouR + OCI_INTER_HOUR_BELOW_VALID 0x80 Bad HouR Low/high bit (1=low) + OCI_INTER_INVALID_MINUTE 0x100 Bad MiNute + OCI_INTER_MINUTE_BELOW_VALID 0x200 Bad MiNute Low/high bit(1=low) + OCI_INTER_INVALID_SECOND 0x400 Bad SeCond + OCI_INTER_SECOND_BELOW_VALID 0x800 bad second Low/high bit(1=low) + OCI_INTER_INVALID_FRACSEC 0x1000 Bad Fractional second + OCI_INTER_FRACSEC_BELOW_VALID 0x2000 Bad fractional second Low/High + + + RETURNS + OCI_SUCCESS if interval is okay + OCI_INVALID_HANDLE if 'err' is NULL. + + ---------------------- OCIIntervalCompare ----------------------------------- +sword OCIIntervalCompare(void *hndl, OCIError *err, OCIInterval *inter1, + OCIInterval *inter2, sword *result ); + + DESCRIPTION + Compares two intervals, returns 0 if equal, -1 if inter1 < inter2, + 1 if inter1 > inter2 + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inter1 (IN) - Interval to be compared + inter2 (IN) - Interval to be compared + result (OUT) - comparison result, 0 if equal, -1 if inter1 < inter2, + 1 if inter1 > inter2 + + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + the two input datetimes are not mutually comparable. + +---------------------- OCIIntervalDivide ------------------------------------ +sword OCIIntervalDivide(void *hndl, OCIError *err, OCIInterval *dividend, + OCINumber *divisor, OCIInterval *result ); + + DESCRIPTION + Divides an interval by an Oracle Number to produce an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + dividend (IN) - Interval to be divided + divisor (IN) - Oracle Number dividing `dividend' + result (OUT) - resulting interval (dividend / divisor) + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + ---------------------- OCIIntervalFromNumber -------------------- +sword OCIIntervalFromNumber(void *hndl, OCIError *err, + OCIInterval *inter, OCINumber *number); + DESCRIPTION + Converts an interval to an Oracle Number + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (OUT) interval - Interval to be converted + (IN) number - Oracle number result (in years for YEARMONTH interval + and in days for DAYSECOND) + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR on error. + NOTES + Fractional portions of the date (for instance, minutes and seconds if + the unit chosen is hours) will be included in the Oracle number produced. + Excess precision will be truncated. + + ---------------------- OCIIntervalFromText --------------------------------- +sword OCIIntervalFromText( void *hndl, OCIError *err, const OraText *inpstr, + size_t str_len, OCIInterval *result ); + + DESCRIPTION + Given an interval string produce the interval represented by the string. + The type of the interval is the type of the 'result' descriptor. + PARAMETERS + + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inpstr - Input string + (IN) str_len - Length of input string + (OUT) result - Resultant interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + there are too many fields in the literal string + the year is out of range (-4713 to 9999) + if the month is out of range (1 to 12) + if the day of month is out of range (1 to 28...31) + if hour is not in range (0 to 23) + if hour is not in range (0 to 11) + if minute is not in range (0 to 59) + if seconds in minute not in range (0 to 59) + if seconds in day not in range (0 to 86399) + if the interval is invalid + + + ---------------------- OCIIntervalGetDaySecond -------------------- + + DESCRIPTION + Gets values of day second interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + day (OUT) - number of days + hour (OUT) - number of hours + min (OUT) - number of mins + sec (OUT) - number of secs + fsec (OUT) - number of fractional seconds + result (IN) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + + ---------------------- OCIIntervalGetYearMonth -------------------- + + DESCRIPTION + Gets year month from an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + year (OUT) - year value + month (OUT) - month value + result (IN) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + + +-------------------------- OCIIntervalAdd ------------------------------ +sword OCIIntervalAdd(void *hndl, OCIError *err, OCIInterval *addend1, + OCIInterval *addend2, OCIInterval *result ); +NAME OCIIntervalAdd - Adds two intervals +PARAMETERS +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +addend1 (IN) - Interval to be added +addend2 (IN) - Interval to be added +result (OUT) - resulting interval (addend1 + addend2) +DESCRIPTION + Adds two intervals to produce a resulting interval +RETURNS + OCI_SUCCESS on success + OCI_ERROR if: + the two input intervals are not mutually comparable. + the resulting year would go above SB4MAXVAL + the resulting year would go below SB4MINVAL + OCI_INVALID_HANDLE if 'err' is NULL. +NOTES + The two input intervals must be mutually comparable + + ---------------------- OCIIntervalSubtract ------------------------------- +sword OCIIntervalSubtract(void *hndl, OCIError *err, OCIInterval *minuend, + OCIInterval *subtrahend, OCIInterval *result ); +NAME - OCIIntervalSubtract - subtracts two intervals +PARAMETERS +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +minuend (IN) - interval to be subtracted from +subtrahend (IN) - interval subtracted from minuend +result (OUT) - resulting interval (minuend - subtrahend) +DESCRIPTION + Subtracts two intervals and stores the result in an interval +RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + the two input intervals are not mutually comparable. + the resulting leading field would go below SB4MINVAL + the resulting leading field would go above SB4MAXVAL + +---------------------- OCIIntervalMultiply --------------------------------- +sword OCIIntervalMultiply(void *hndl, OCIError *err, const OCIInterval *inter, + OCINumber *nfactor, OCIInterval *result ); + + DESCRIPTION + Multiplies an interval by an Oracle Number to produce an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inter (IN) - Interval to be multiplied + nfactor (IN) - Oracle Number to be multiplied + result (OUT) - resulting interval (ifactor * nfactor) + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + the resulting year would go above SB4MAXVAL + the resulting year would go below SB4MINVAL + + + ---------------------- OCIIntervalSetDaySecond -------------------- + + DESCRIPTION + Sets day second interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + day (IN) - number of days + hour (IN) - number of hours + min (IN) - number of mins + sec (IN) - number of secs + fsec (IN) - number of fractional seconds + result (OUT) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + + ---------------------- OCIIntervalSetYearMonth -------------------- + + DESCRIPTION + Sets year month interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + year (IN) - year value + month (IN) - month value + result (OUT) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + +----------------------- OCIIntervalToNumber --------------------------------- +sword OCIIntervalToNumber(void *hndl, OCIError *err, const OCIInterval *inter, + OCINumber *number); + + DESCRIPTION + Converts an interval to an Oracle Number + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inter - Interval to be converted + (OUT) number - Oracle number result (in years for YEARMONTH interval + and in days for DAYSECOND) + RETURNS + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_SUCCESS on success + NOTES + Fractional portions of the date (for instance, minutes and seconds if + the unit chosen is hours) will be included in the Oracle number produced. + Excess precision will be truncated. + +------------------------------- OCIIntervalToText ------------------------- +sword OCIIntervalToText( void *hndl, OCIError *err, const OCIInterval *inter, + ub1 lfprec, ub1 fsprec, OraText *buffer, + size_t buflen, size_t *resultlen ); + + DESCRIPTION + Given an interval, produces a string representing the interval. + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inter - Interval to be converted + (IN) lfprec - Leading field precision. Number of digits used to + represent the leading field. + (IN) fsprec - Fractional second precision of the interval. Number of + digits used to represent the fractional seconds. + (OUT) buffer - buffer to hold result + (IN) buflen - length of above buffer + (OUT) resultlen - length of result placed into buffer + + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR + if the buffer is not large enough to hold the result + NOTES + The interval literal will be output as `year' or `[year-]month' for + YEAR-MONTH intervals and as `seconds' or `minutes[:seconds]' or + `hours[:minutes[:seconds]]' or `days[ hours[:minutes[:seconds]]]' for + DAY-TIME intervals (where optional fields are surrounded by brackets). + + ---------------------- OCIIntervalFromTZ -------------------- +sword OCIIntervalFromTZ(void *hndl, OCIError *err, const oratext *inpstring, + size_t str_len, OCIInterval *result); + + DESCRIPTION + Retuns an OCI_DTYPE_INTERVAL_DS OCIInterval with the region id (if + the region is specified in the input string) set and the current + absolute offset or an absolut offset with the region id set to 0. + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inpstring (IN) - pointer to the input string + str_len (IN) - inpstring length + result - Output Interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR on error + Bad interval type + Timezone errors + NOTES + The input string must be of the form [+/-]TZH:TZM or 'TZR [TZD]' + + ----------------------- OCIKerbAttrSet --------------------- +sword OCIKerbAttrSet(OCISession *trgthndlp, ub4 auth_mode, + ub1 *ftgt_ticket, ub4 ftgt_ticket_len, + ub1 *ftgt_sesskey, ub4 ftgt_sesskey_len, + ub2 ftgt_keytype, ub4 ftgt_ticket_flags, + sb4 ftgt_auth_time, sb4 ftgt_start_time, + sb4 ftgt_end_time, sb4 ftgt_renew_time, + oratext *ftgt_principal, ub4 ftgt_principal_len, + oratext *ftgt_realm, ub4 ftgt_realm_len, + OCIError *errhp); + + DESCRIPTION + This call sets the attributes required for Kerberos authentication + on the user handle. + + PARAMETERS + trgthndlp (IN) - The pointer to a user handle. + auth_mode (IN) - Indicates what type of Kerberos credentials should + be set. Options are: + + OCI_KERBCRED_PROXY + - Set Kerberos credentials for use with + proxy authentication. + OCI_KERBCRED_CLIENT_IDENTIFIER + - Set Kerberos credentials for use + with secure client identifier. + + ftgt_ticket (IN) - Forwardable Ticket Granting Ticket (FTGT). + ftgt_ticket_len (IN) - Length of FTGT. + ftgt_sesskey(IN) - Session Key associated with FTGT. + ftgt_sesskey_len (IN) - Length of session key. + ftgt_keytype (IN) - Type of encryption key used to encrypt FTGT. + ftgt_ticket_flags (IN) - Flags associated with encryption of FTGT. + ftgt_auth_time (IN) - Authentication time compatible with that in FTGT. + ftgt_start_time (IN) - Start time compatible with that indicated in FTGT. + ftgt_end_time (IN) - End time compatible with that indicated in FTGT. + ftgt_renew_time (IN) - Renew time compatible with that indicated in FTGT. + ftgt_principal (IN) - Client principal name from FTGT. + ftgt_principal_len (IN) - Length of client principal name. + ftgt_realm (IN) - Client realm name from FTGT. + ftgt_realm_len (IN) - Client realm name length. + errhp (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + RETURNS + OCI_SUCCESS on success + OCI_ERROR on error + NOTES + +OCILdaToSvcCtx() +Name +OCI toggle version 7 Lda_Def to SerVice context handle +Purpose +Converts a V7 Lda_Def to a V8 service context handle. +Syntax +sword OCILdaToSvcCtx ( OCISvcCtx **svchpp, + OCIError *errhp, + Lda_Def *ldap ); +Comments +Converts a V7 Lda_Def to a V8 service context handle. The action of this call +can be reversed by passing the resulting service context handle to the +OCISvcCtxToLda() function. +Parameters +svchpp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +ldap (IN/OUT) - the V7 logon data area returned by OCISvcCtxToLda() from +this service context. +Related Functions +OCISvcCtxToLda() + + + + +OCILobAppend() + +Name +OCI Lob APpend + +Purpose +Appends a LOB value at the end of another LOB. + +Syntax +sword OCILobAppend ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp ); +Comments +Appends a LOB value at the end of LOB. The data is +copied from the source to the destination at the end of the destination. The +source and the destination must already exist. The destination LOB is +extended to accommodate the newly written data. + +It is an error to extend the destination LOB beyond the maximum length +allowed or to try to copy from a NULL LOB. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dst_locp (IN/OUT) - a locator uniquely referencing the destination LOB. +src_locp (IN/OUT) - a locator uniquely referencing the source LOB. + +Related Functions +OCILobTrim() +OCIErrorGet() +OCILobWrite() +OCILobCopy() + + + +OCILobAssign() + +Name +OCI Lob ASsiGn + +Purpose +Assigns one LOB/FILE locator to another. + +Syntax +sword OCILobAssign ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp ); + +Comments +Assign source locator to destination locator. After the assignment, both +locators refer to the same LOB data. For internal LOBs, the source locator's +LOB data gets copied to the destination locator's LOB data only when the +destination locator gets stored in the table. Therefore, issuing a flush of +the object containing the destination locator will copy the LOB data. For +FILEs only the locator that refers to the OS file is copied to the table. The +OS file is not copied. +Note: The only difference between this and OCILobLocatorAssign is that this +takes an environment handle whereas OCILobLocatorAssign takes an OCI service +handle + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded +in errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +src_locp (IN) - LOB locator to copy from. +dst_locpp (IN/OUT) - LOB locator to copy to. The caller must allocate space +for the OCILobLocator by calling OCIDescriptorAlloc(). + +See also +OCIErrorGet() +OCILobIsEqual() +OCILobLocatorIsInit() +OCILobLocatorAssign() + + +OCILobCharSetForm() + +Name +OCI Lob Get Character Set Form + +Purpose +Gets the LOB locator's character set fpr,, if any. + +Syntax +sword OCILobCharSetForm ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *locp, + ub1 *csfrm ); + +Comments +Returns the character set form of the input LOB locator in the csfrm output +parameter. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +locp (IN) - LOB locator for which to get the character set form. +csfrm(OUT) - character set form of the input LOB locator. If the input +locator is for a BLOB or a BFILE, csfrm is set to 0 since there is no concept +of a character set for binary LOBs/FILEs. The caller must allocate space for +the csfrm (ub1) and not write into the space. +See also +OCIErrorGet(), OCILobCharSetId(), OCILobLocatorIsInit + + + +OCILobCharSetId() + +Name +OCI Lob get Character Set IDentifier + +Purpose +Gets the LOB locator's character set ID, if any. + +Syntax +sword OCILobCharSetId ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *locp, + ub2 *csid ); + +Comments +Returns the character set ID of the input LOB locator in the cid output +parameter. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +locp (IN) - LOB locator for which to get the character set ID. +csid (OUT) - character set ID of the input LOB locator. If the input locator +is for a BLOB or a BFILE, csid is set to 0 since there is no concept of a +character set for binary LOBs/FILEs. The caller must allocate space for the +character set id of type ub2 and not write into the space. + +See also +OCIErrorGet(), OCILobCharSetForm(), OCILobLocatorIsInit() + + + +OCILobCopy() + +Name +OCI Lob Copy + +Purpose +Copies a portion of a LOB value into another LOB value. + +Syntax +sword OCILobCopy ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp, + ub4 amount, + ub4 dst_offset, + ub4 src_offset ); + +Comments +Copies a portion of a LOB value into another LOB as specified. The data +is copied from the source to the destination. The source (src_locp) and the +destination (dlopb) LOBs must already exist. +If the data already exists at the destination's start position, it is +overwritten with the source data. If the destination's start position is +beyond the end of the current data, a hole is created from the end of the data +to the beginning of the newly written data from the source. The destination +LOB is extended to accommodate the newly written data if it extends +beyond the current length of the destination LOB. +It is an error to extend the destination LOB beyond the maximum length +allowed or to try to copy from a NULL LOB. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dst_locp (IN/OUT) - a locator uniquely referencing the destination LOB. +src_locp (IN/OUT) - a locator uniquely referencing the source LOB. +amount (IN) - the number of character or bytes, as appropriate, to be copied. +dst_offset (IN) - this is the absolute offset for the destination LOB. +For character LOBs it is the number of characters from the beginning of the +LOB at which to begin writing. For binary LOBs it is the number of bytes from +the beginning of the lob from which to begin reading. The offset starts at 1. +src_offset (IN) - this is the absolute offset for the source LOB. +For character LOBs it is the number of characters from the beginning of the +LOB, for binary LOBs it is the number of bytes. Starts at 1. + +See Also +OCIErrorGet(), OCILobAppend(), OCILobWrite(), OCILobTrim() + +OCILobCreateTemporary() + +Name +OCI Lob Create Temporary + +Purpose +Create a Temporary Lob + +Syntax +sword OCILobCreateTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub2 csid, + ub1 csfrm, + ub1 lobtype, + boolean cache, + OCIDuration duration); + + +Comments +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator which points to the temporary Lob +csid (IN) - the character set id +csfrm(IN) - the character set form +lobtype (IN) - the lob type - one of the three constants OCI_TEMP_BLOB, + OCI_TEMP_CLOB and OCI_TEMP_NCLOB +cache(IN)- TRUE if the temporary LOB goes through the cache; FALSE, if not. +duration(IN)- duration of the temporary LOB; Can be a valid duration id or one + of the values: OCI_DURATION_SESSION, OCI_DURATION_CALL + Note: OCI_DURATION_TRANSACTION is NOT supported in 8.1 +Related functions +OCILobFreeTemporary() +OCILobIsTemporary() + +OCILobDisableBuffering() + +Name +OCI Lob Disable Buffering + +Purpose +Disable lob buffering for the input locator. + + +Syntax +sword OCILobDisableBuffering ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +Comments + +Disable lob buffering for the input locator. The next time data is +read/written from/to the lob through the input locator, the lob +buffering subsystem is *not* used. Note that this call does *not* +implicitly flush the changes made in the buffering subsystem. The +user must explicitly call OCILobFlushBuffer() to do this. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB. + +Related Functions +OCILobEnableBuffering() +OCIErrorGet() +OCILobFlushBuffer() + + + + +OCILobEnableBuffering() + +Name +OCI Lob Enable Buffering + +Purpose +Enable lob buffering for the input locator. + + +Syntax +sword OCILobEnableBuffering ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +Comments + +Enable lob buffering for the input locator. The next time data is +read/written from/to the lob through the input locator, the lob +buffering subsystem is used. + +Once lob buffering is enabled for a locator, if that locator is passed to +one of the following routines, an error is returned: + OCILobCopy, OCILobAppend, OCILobErase, OCILobGetLength, OCILobTrim + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB. + +Related Functions +OCILobDisableBuffering() +OCIErrorGet() +OCILobWrite() +OCILobRead() +OCILobFlushBuffer() + + + + +OCILobErase() + +Name +OCI Lob ERase + +Purpose +Erases a specified portion of the LOB data starting at a specified offset. + +Syntax +sword OCILobErase ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *amount, + ub4 offset ); + +Comments +Erases a specified portion of the LOB data starting at a specified offset. +The actual number of characters/bytes erased is returned. The actual number +of characters/bytes and the requested number of characters/bytes will differ +if the end of the LOB data is reached before erasing the requested number of +characters/bytes. +If a section of data from the middle of the LOB data is erased, a hole is +created. When data from that hole is read, 0's are returned. If the LOB is +NULL, this routine will indicate that 0 characters/bytes were erased. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - the LOB for which to erase a section of data. +amount (IN/OUT) - On IN, the number of characters/bytes to erase. On OUT, +the actual number of characters/bytes erased. +offset (IN) - absolute offset from the beginning of the LOB data from which +to start erasing data. Starts at 1. + +See Also +OCIErrorGet(), OCILobRead(), OCILobWrite() + +OCILobOpen() + +Name +OCI Lob Open + +Purpose +Opens an internal or external Lob. + +Syntax +sword OCILobOpen( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub1 mode ); + +Comments +It is an error if the same lob is opened more than once in +the same transaction. Lobs are opened implicitly if they are +not opened before using them. A LOB has to be closed before +the transaction commits else the transaction is rolled back. +Open locators are closed if the transaction aborts. Multiple +users can open the same lob on different locators. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - locator points to the LOB to be opened +mode (IN) - mode in which to open the lob. The valid modes are +read-only - OCI_FILE_READONLY, read-write - OCI_FILE_READWRITE + +OCILobClose() + +Name +OCI Lob Close + +Purpose +Closes an open internal or external Lob. + +Syntax +sword OCILobClose( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp ); + + +Comments +It is an error if the lob is not open at this time. All LOBs +that have been opened in a transaction have to be closed +before the transaction commits, else the transaction gets +rolled back. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN) - A locator that was opened using OCILobOpen() + + +OCILobFileClose() + +Name +OCI Lob File CLoSe + +Purpose +Closes a previously opened FILE. + +Syntax +sword OCILobFileClose ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep ); + +Comments +Closes a previously opened FILE. It is an error if this function is called for +an internal LOB. No error is returned if the FILE exists but is not opened. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +filep (IN/OUT) - a pointer to a FILE locator to be closed. + +See Also +OCIErrorGet(), OCILobFileOpen(), OCILobFileCloseAll(), OCILobFileIsOpen(), +OCILobFileExists(), CREATE DIRECTORY DDL + + + + +OCILobFileCloseAll() + +Name +OCI LOB FILE Close All + +Purpose +Closes all open FILEs on a given service context. + +Syntax +sword OCILobFileCLoseAll ( OCISvcCtx *svchp, + OCIError *errhp ); + +Comments +Closes all open FILEs on a given service context. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. + +See also +OCILobFileClose(), +OCIErrorGet(), OCILobFileOpen(), OCILobFileIsOpen(), +OCILobFileExists(), CREATE DIRECTORY DDL + + + + +OCILobFileExists() + +Name +OCI LOB FILE exists + +Purpose +Tests to see if the FILE exists on the server + +Syntax +sword OCILobFileExists ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep, + boolean *flag ); + +Comments +Checks to see if a FILE exists for on the server. + +Parameters +svchp (IN) - the OCI service context handle. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, +it is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +filep (IN) - pointer to the FILE locator that refers to the file. +flag (OUT) - returns TRUE if the FILE exists; FALSE if it does not. + +See also +OCIErrorGet, CREATE DIRECTORY (DDL) + + + + +OCILobFileGetName() + +Name +OCI LOB FILE Get file Name + +Purpose +Gets the FILE locator's directory alias and file name. + +Syntax +sword OCILobFileGetName ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *filep, + OraText *dir_alias, + ub2 *d_length, + OraText *filename, + ub2 *f_length ); + +Comments +Returns the directory alias and file name associated with this file locator. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) -The OCI error handle. If there is an error, it is recorded in +errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +filep (IN) - FILE locator for which to get the directory alias and file name. +dir_alias (OUT) - buffer into which the directory alias name is placed. The +caller must allocate enough space for the directory alias name and must not +write into the space. +d_length (IN/OUT) + - IN: length of the input dir_alias string; + - OUT: length of the returned dir_alias string. +filename (OUT) - buffer into which the file name is placed. The caller must +allocate enough space for the file name and must not write into the space. +f_length (IN/OUT) + - IN: length of the input filename string; + - OUT: lenght of the returned filename string. + +See also +OCILobFileSetName(), OCIErrorGet() + + + + +OCILobFileIsOpen() + +Name +OCI LOB FILE Is Open? + +Purpose +Tests to see if the FILE is open + +Syntax +sword OCILobFileIsOpen ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep, + boolean *flag ); + +Comments +Checks to see if the FILE on the server is open for a given LobLocator. + +Parameters +svchp (IN) - the OCI service context handle. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +filep (IN) - pointer to the FILE locator being examined. If the input file +locator was never passed to OCILobFileOpen(), the file is considered not to +be opened by this locator. However, a different locator may have opened the +file. More than one file opens can be performed on the same file using +different locators. +flag (OUT) - returns TRUE if the FILE is opened using this locator; FALSE if +it is not. + +See also +OCIErrorGet, OCILobFileOpen, OCILobFileClose, OCILobFileCloseAll, CREATE +DIRECTORY SQL command + + +OCILobFileOpen() + +Name +OCI LOB FILE open + +Purpose +Opens a FILE for read-only access + +Syntax +sword OCILobFileOpen ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep, + ub1 mode ); + +Comments +Opens a FILE. The FILE can be opened for read-only access only. FILEs may not +be written to throough ORACLE. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +filep (IN/OUT) - the FILE to open. Error if the locator does not refer to a +FILE. +mode (IN) - mode in which to open the file. The only valid mode is +read-only - OCI_FILE_READONLY. + +See Also +OCILobFileClose, OCIErrorGet, OCILobFileCloseAll, OCILobFileIsOpen, +OCILobFileSetName, CREATE DIRECTORY + + + + +OCILobFileSetName() + +Name +OCI Lob File Set NaMe + +Purpose +Sets directory alias and file name in the FILE locator. + +Syntax +sword OCILobFileSetName ( OCIEnv *envhp, + OCIError *errhp, + OCILobLocator **filepp, + OraText *dir_alias, + ub2 d_length, + OraText *filename, + ub2 f_length ); +Comments +Sets the directory alias and file name in the LOB file locator. +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded +in errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +filepp (IN/OUT) - FILE locator for which to set the directory alias name. +The caller must have already allocated space for the locator by calling +OCIDescriptorAlloc(). +dir_alias (IN) - buffer that contains the directory alias name to set in the +locator. +d_length (IN) - length of the input dir_alias parameter. +filename (IN) - buffer that contains the file name is placed. +f_length (IN) - length of the input filename parameter. +See also +OCILobFileGetName, OCIErrorGet, CREATE DIRECTORY + + + + +OCILobFlushBuffer() + +Name +OCI Lob Flush all Buffers for this lob. + +Purpose +Flush/write all buffers for this lob to the server. + + +Syntax +sword OCILobFlushBuffer ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 flag); + +Comments + +Flushes to the server, changes made to the buffering subsystem that +are associated with the lob referenced by the input locator. This +routine will actually write the data in the buffer to the lob in +the database. Lob buffering must have already been enabled for the +input lob locator. + +This routine, by default, does not free the buffer resources for +reallocation to another buffered LOB operation. However, if you +want to free the buffer explicitly, you can set the flag parameter +to OCI_LOB_BUFFER_FREE. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB. +flag (IN) - to indicate if the buffer resources need to be freed + after a flush. Default value is OCI_LOB_BUFFER_NOFREE. + Set it to OCI_LOB_BUFFER_FREE if you want the buffer + resources to be freed. +Related Functions +OCILobEnableBuffering() +OCILobDisableBuffering() +OCIErrorGet() +OCILobWrite() +OCILobRead() + + +OCILobFreeTemporary() + +Name +OCI Lob Free Temporary + +Purpose +Free a temporary LOB + +Syntax +sword OCILobFreeTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +Comments + Frees the contents of the temporary Lob this locator is pointing to. Note + that the locator itself is not freed until a OCIDescriptorFree is done. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB + +Related functions +OCILobCreateTemporary() +OCILobIsTemporary() + + +Name +OCI Lob/File Get Chunk Size + +Purpose +When creating the table, the user can specify the chunking factor, which can +be a multiple of Oracle blocks. This corresponds to the chunk size used by the +LOB data layer when accessing/modifying the LOB value. Part of the chunk is +used to store system-related information and the rest stores the LOB value. +This function returns the amount of space used in the LOB chunk to store +the LOB value. + +Syntax +sword OCILobGetChunkSize ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *chunksizep ); + +Comments + Performance will be improved if the user issues read/write +requests using a multiple of this chunk size. For writes, there is an added +benefit since LOB chunks are versioned and, if all writes are done on chunk +basis, no extra/excess versioning is done nor duplicated. Users could batch +up the write until they have enough for a chunk instead of issuing several +write calls for the same chunk. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references the LOB. For internal +LOBs, this locator must be a locator that was obtained from the server +specified by svchp. For FILEs, this locator can be initialized by a Select or +OCILobFileSetName. +chunksizep (OUT) - On output, it is the length of the LOB if not NULL - for +character LOBs it is the number of characters, for binary LOBs it is the +number of bytes in the LOB. + +Related Functions + +OCILobGetLength() + +Name +OCI Lob/File Length + +Purpose +Gets the length of a LOB/FILE. + +Syntax +sword OCILobGetLength ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *lenp ); + +Comments +Gets the length of a LOB/FILE. If the LOB/FILE is NULL, the length is +undefined. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references the LOB. For internal +LOBs, this locator must be a locator that was obtained from the server +specified by svchp. For FILEs, this locator can be initialized by a Select or +OCILobFileSetName. +lenp (OUT) - On output, it is the length of the LOB if not NULL - for +character LOBs it is the number of characters, for binary LOBs it is the +number of bytes in the LOB. + +Related Functions +OCIErrorGet, OCIFileSetName + + + +OCILobIsEqual() + +Name + +OCI Lob Is Equal + +Purpose +Compares two LOB locators for equality. + +Syntax +sword OCILobIsEqual ( OCIEnv *envhp, + const OCILobLocator *x, + const OCILobLocator *y, + boolean *is_equal ); + +Comments +Compares the given LOB locators for equality. Two LOB locators are equal if +and only if they both refer to the same LOB data. +Two NULL locators are considered not equal by this function. +Parameters +envhp (IN) - the OCI environment handle. +x (IN) - LOB locator to compare. +y (IN) - LOB locator to compare. +is_equal (OUT) - TRUE, if the LOB locators are equal; FALSE if they are not. + +See also +OCILobAssign, OCILobLocatorIsInit +OCILobLocatorAssign, +OCILobIsOpen() + +Name + +OCI Lob Is Open +sword OCILobIsOpen(svchp, errhp, locp, flag) +OCISvcCtx *svchp; +OCIError *errhp; +OCILobLocator *locp; +boolean *flag; + +Comments + Checks if the LOB locator was opened before. flag is set to TRUE + if opened; FALSE otherwise + + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN) - the locator to test for temporary LOB +flag(OUT) - TRUE, if the LOB locator points to is open + FALSE, if not. + +OCILobIsTemporary() + +Name + +OCI Lob Is Temporary + +Purpose + Tests if this locator points to a temporary LOB + +Syntax +sword OCILobIsTemporary(OCIEnv *envhp, + OCIError *errhp, + OCILobLocator *locp, + boolean *is_temporary); + +Comments +Tests the locator to determine if it points to a temporary LOB. +If so, is_temporary is set to TRUE. If not, is_temporary is set +to FALSE. + +Parameters +envhp (IN) - the environment handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN) - the locator to test for temporary LOB +is_temporary(OUT) - TRUE, if the LOB locator points to a temporary LOB; + FALSE, if not. + +See Also +OCILobCreateTemporary, OCILobFreeTemporary + + +OCILobLoadFromFile() + +Name +OCI Lob Load From File + +Purpose +Load/copy all or a portion of the file into an internal LOB. + +Syntax +sword OCILobLoadFromFile ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + ub4 amount, + ub4 dst_offset, + ub4 src_offset ); + +Comments +Loads/copies a portion or all of a file value into an internal LOB as +specified. The data is copied from the source file to the destination +internal LOB (BLOB/CLOB). No character set conversions are performed +when copying the bfile data to a clob/nclob. The bfile data must already +be in the same character set as the clob/nclob in the database. No +error checking is performed to verify this. +The source (src_filep) and the destination (dst_locp) LOBs must already exist. +If the data already exists at the destination's start position, it is +overwritten with the source data. If the destination's start position is +beyond the end of the current data, a hole is created from the end of the data +to the beginning of the newly written data from the source. The destination +LOB is extended to accommodate the newly written data if it extends +beyond the current length of the destination LOB. +It is an error to extend the destination LOB beyond the maximum length +allowed or to try to copy from a NULL LOB. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dst_locp (IN/OUT) - a locator uniquely referencing the destination internal +LOB which may be of type blob, clob, or nclob. +src_filep (IN/OUT) - a locator uniquely referencing the source BFILE. +amount (IN) - the number of bytes to be copied. +dst_offset (IN) - this is the absolute offset for the destination LOB. +For character LOBs it is the number of characters from the beginning of the +LOB at which to begin writing. For binary LOBs it is the number of bytes from +the beginning of the lob from which to begin reading. The offset starts at 1. +src_offset (IN) - this is the absolute offset for the source BFILE. It is +the number of bytes from the beginning of the LOB. The offset starts at 1. + +See Also +OCIErrorGet(), OCILobAppend(), OCILobWrite(), OCILobTrim(), OCILobCopy() + +OCILobLocatorAssign() + +Name +OCI Lob LOCATOR ASsiGn + +Purpose +Assigns one LOB/FILE locator to another. + +Syntax +sword OCILobLocatorAssign ( OCISvcCtx *svchp, + OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp ); + +Comments +Assign source locator to destination locator. After the assignment, both +locators refer to the same LOB data. For internal LOBs, the source locator's +LOB data gets copied to the destination locator's LOB data only when the +destination locator gets stored in the table. Therefore, issuing a flush of +the object containing the destination locator will copy the LOB data. For +FILEs only the locator that refers to the OS file is copied to the table. The +OS file is not copied. +Note : the only difference between this and OCILobAssign is that this takes +a OCI service handle pointer instead of a OCI environment handle pointer + +Parameters +svchp (IN/OUT) - OCI service handle initialized in object mode. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded +in errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +src_locp (IN) - LOB locator to copy from. +dst_locpp (IN/OUT) - LOB locator to copy to. The caller must allocate space +for the OCILobLocator by calling OCIDescriptorAlloc(). + +See also +OCIErrorGet() +OCILobIsEqual() +OCILobLocatorIsInit() +OCILobAssign() + + + + +OCILobLocatorIsInit() + +Name +OCI LOB locator is initialized? + +Purpose +Tests to see if a given LOB locator is initialized. + +Syntax +sword OCILobLocatorIsInit ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *locp, + boolean *is_initialized ); + +Comments +Tests to see if a given LOB locator is initialized. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +locp (IN) - the LOB locator being tested +is_initialized (OUT) - returns TRUE if the given LOB locator is initialized; +FALSE if it is not. + +See also +OCIErrorGet, OCILobIsEqual + + + + +OCILobRead() + +Name +OCI Lob/File ReaD + +Purpose +Reads a portion of a LOB/FILE as specified by the call into a buffer. + +Syntax +sword OCILobRead ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 offset, + ub4 *amtp, + void *bufp, + ub4 bufl, + void *ctxp, + OCICallbackLobRead cbfp, + ub2 csid, + ub1 csfrm ); + +Comments +Reads a portion of a LOB/FILE as specified by the call into a buffer. Data +read from a hole is returned as 0s. It is an error to try to read from a NULL +LOB/FILE. The OS FILE must already exist on the server and must have been +opened using the input locator. Oracle must hav epermission to read the OS +file and user must have read permission on the directory object. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +offset (IN) - On input, it is the absolute offset, for character LOBs in the +number of characters from the beginning of the LOB, for binary LOBs it is the +number of bytes. Starts from 1. +amtp (IN/OUT) - On input, the number of character or bytes to be read. On +output, the actual number of bytes or characters read. +If the amount of bytes to be read is larger than the buffer length it is +assumed that the LOB is being read in a streamed mode. On input if this value +is 0, then the data shall be read in streamed mode from the LOB until the end +of LOB. If the data is read in pieces, *amtp always contains the length of +the last piece read. If a callback function is defined, then this callback +function will be invoked each time bufl bytes are read off the pipe. Each +piece will be written into bufp. +If the callback function is not defined, then OCI_NEED_DATA error code will +be returned. The application must invoke the LOB read over and over again to +read more pieces of the LOB until the OCI_NEED_DATA error code is not +returned. The buffer pointer and the length can be different in each call +if the pieces are being read into different sizes and location. +bufp (IN) - the pointer to a buffer into which the piece will be read. The +length of the allocated memory is assumed to be bufl. +bufl (IN) - the length of the buffer in octets. +ctxp (IN) - the context for the call back function. Can be NULL. +cbfp (IN) - a callback that may be registered to be called for each piece. If +this is NULL, then OCI_NEED_DATA will be returned for each piece. +The callback function must return OCI_CONTINUE for the read to continue. +If any other error code is returned, the LOB read is aborted. + ctxp (IN) - the context for the call back function. Can be NULL. + bufp (IN) - a buffer pointer for the piece. + len (IN) - the length of length of current piece in bufp. + piece (IN) - which piece - OCI_FIRST_PIECE, OCI_NEXT_PIECE or + OCI_LAST_PIECE. +csid - the character set ID of the buffer data +csfrm - the character set form of the buffer data + +Related Functions +OCIErrorGet, OCILobWrite, OCILobFileOpen, OCILobFileSetName, CREATE DIRECTORY + + + + +OCILobTrim() + +Name + +OCI Lob Trim + +Purpose +Trims the lob value to a shorter length + +Syntax +sword OCILobTrim ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 newlen ); + +Comments +Truncates LOB data to a specified shorter length. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references the LOB. This locator +must be a locator that was obtained from the server specified by svchp. +newlen (IN) - the new length of the LOB data, which must be less than or equal +to the current length. + +Related Functions +OCIErrorGet, OCILobWrite, OCiLobErase, OCILobAppend, OCILobCopy + + + + + +OCILobWrite() + +Name +OCI Lob Write + +Purpose +Writes a buffer into a LOB + +Syntax +sword OCILobWrite ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 offset, + ub4 *amtp, + void *bufp, + ub4 buflen, + ub1 piece, + void *ctxp, + OCICallbackLobWrite (cbfp) + ( + void *ctxp, + void *bufp, + ub4 *lenp, + ub1 *piecep ) + ub2 csid + ub1 csfrm ); + + +Comments +Writes a buffer into a LOB as specified. If LOB data already exists +it is overwritten with the data stored in the buffer. +The buffer can be written to the LOB in a single piece with this call, or +it can be provided piecewise using callbacks or a standard polling method. +If this value of the piece parameter is OCI_FIRST_PIECE, data must be +provided through callbacks or polling. +If a callback function is defined in the cbfp parameter, then this callback +function will be invoked to get the next piece after a piece is written to +the pipe. Each piece will be written from bufp. +If no callback function is defined, then OCILobWrite() returns the +OCI_NEED_DATA error code. The application must all OCILobWrite() again +to write more pieces of the LOB. In this mode, the buffer pointer and the +length can be different in each call if the pieces are of different sizes and +from different locations. A piece value of OCI_LAST_PIECE terminates the +piecewise write. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +offset (IN) - On input, it is the absolute offset, for character LOBs in +the number of characters from the beginning of the LOB, for binary LOBs it +is the number of bytes. Starts at 1. +bufp (IN) - the pointer to a buffer from which the piece will be written. The +length of the allocated memory is assumed to be the value passed in bufl. +Even if the data is being written in pieces, bufp must contain the first +piece of the LOB when this call is invoked. +bufl (IN) - the length of the buffer in bytes. +Note: This parameter assumes an 8-bit byte. If your platform uses a +longer byte, the value of bufl must be adjusted accordingly. +piece (IN) - which piece of the buffer is being written. The default value for +this parameter is OCI_ONE_PIECE, indicating the buffer will be written in a +single piece. +The following other values are also possible for piecewise or callback mode: +OCI_FIRST_PIECE, OCI_NEXT_PIECE and OCI_LAST_PIECE. +amtp (IN/OUT) - On input, takes the number of character or bytes to be +written. On output, returns the actual number of bytes or characters written. +If the data is written in pieces, *amtp will contain the total length of the +pieces written at the end of the call (last piece written) and is undefined in +between. +(Note it is different from the piecewise read case) +ctxp (IN) - the context for the call back function. Can be NULL. +cbfp (IN) - a callback that may be registered to be called for each piece in +a piecewise write. If this is NULL, the standard polling method will be used. +The callback function must return OCI_CONTINUE for the write to continue. +If any other error code is returned, the LOB write is aborted. The +callback takes the following parameters: + ctxp (IN) - the context for the call back function. Can be NULL. + bufp (IN/OUT) - a buffer pointer for the piece. + lenp (IN/OUT) - the length of the buffer (in octets) and the length of + current piece in bufp (out octets). + piecep (OUT) - which piece - OCI_NEXT_PIECE or OCI_LAST_PIECE. +csid - the character set ID of the buffer data +csfrm - the character set form of the buffer data +Related Functions + +OCILobWriteAppend() + +Name +OCI Lob Write Append + +Purpose +Writes data to the end of a LOB value. This call provides the ability +to get the length of the data and append it to the end of the LOB in +a single round trip to the server. + +Syntax +sword OCILobWriteAppend ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *amtp, + void *bufp, + ub4 buflen, + ub1 piece, + void *ctxp, + OCICallbackLobWrite (cbfp) + ( + void *ctxp, + void *bufp, + ub4 *lenp, + ub1 *piecep ) + ub2 csid + ub1 csfrm ); + + +Comments +Writes a buffer to the end of a LOB as specified. If LOB data already exists +it is overwritten with the data stored in the buffer. +The buffer can be written to the LOB in a single piece with this call, or +it can be provided piecewise using callbacks or a standard polling method. +If this value of the piece parameter is OCI_FIRST_PIECE, data must be +provided through callbacks or polling. +If a callback function is defined in the cbfp parameter, then this callback +function will be invoked to get the next piece after a piece is written to the +pipe. Each piece will be written from bufp. +If no callback function is defined, then OCILobWriteAppend() returns the +OCI_NEED_DATA error code. The application must all OCILobWriteAppend() again +to write more pieces of the LOB. In this mode, the buffer pointer and the +length can be different in each call if the pieces are of different sizes and +from different locations. A piece value of OCI_LAST_PIECE terminates the +piecewise write. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +bufp (IN) - the pointer to a buffer from which the piece will be written. The +length of the allocated memory is assumed to be the value passed in bufl. Even +if the data is being written in pieces, bufp must contain the first piece of +the LOB when this call is invoked. +bufl (IN) - the length of the buffer in bytes. +Note: This parameter assumes an 8-bit byte. If your platform uses a +longer byte, the value of bufl must be adjusted accordingly. +piece (IN) - which piece of the buffer is being written. The default value for +this parameter is OCI_ONE_PIECE, indicating the buffer will be written in a +single piece. +The following other values are also possible for piecewise or callback mode: +OCI_FIRST_PIECE, OCI_NEXT_PIECE and OCI_LAST_PIECE. +amtp (IN/OUT) - On input, takes the number of character or bytes to be +written. On output, returns the actual number of bytes or characters written. +If the data is written in pieces, *amtp will contain the total length of the +pieces written at the end of the call (last piece written) and is undefined in +between. +(Note it is different from the piecewise read case) +ctxp (IN) - the context for the call back function. Can be NULL. +cbfp (IN) - a callback that may be registered to be called for each piece in a +piecewise write. If this is NULL, the standard polling method will be used. +The callback function must return OCI_CONTINUE for the write to continue. +If any other error code is returned, the LOB write is aborted. The +callback takes the following parameters: + ctxp (IN) - the context for the call back function. Can be NULL. + bufp (IN/OUT) - a buffer pointer for the piece. + lenp (IN/OUT) - the length of the buffer (in octets) and the length of + current piece in bufp (out octets). + piecep (OUT) - which piece - OCI_NEXT_PIECE or OCI_LAST_PIECE. +csid - the character set ID of the buffer data +csfrm - the character set form of the buffer data +Related Functions + + + + +OCILobGetStorageLimit() + +Name +OCI Lob Get Storage Limit + +Purpose +To get the maximum Length of a LOB in bytes that can be stored in the database. + +Syntax +sword OCILobGetStorageLimit ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + oraub8 *limitp); + + +Comments +With unlimited size LOB support the limit for a LOB is no longer restricted +to 4GB. +This interface should be used to get the actual limit for storing data for +a specific +LOB locator. Note that if the compatibality is set to 9.2 or older the limit +would still be 4GB. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +limitp (OUT) - The storage limit for a LOB in bytes. +Related Functions + + + + +OCILobGetOptions() + +Name +OCI Lob Get Options + +Purpose +To get the current options set for the given SecureFile. + +Syntax +sword OCILobGetOptions ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 optypes, + void *optionsp, + ub4 *optionslenp, + ub4 mode); + + +Comments +This function only works on SecureFiles. All others will get an error. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +optypes (IN) - the types of options flags to be retrieved. +optionsp (OUT) - the options flags or value for the given types. +optionslenp (IN/OUT) - the length of option_value buffer +mode (IN) - for future use (pass 0 for now). +Related Functions +OCISetOptions() + +OCILobSetOptions() + +Name +OCI Lob Set Options + +Purpose +To set the options for the given SecureFile Lob. + +Syntax +sword OCILobSetOptions ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 optypes, + void *optionsp, + ub4 optionslen, + ub4 mode); + + +Comments +This function only works on SecureFile Lobs. All others will get an error. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +optypes (IN) - the types of options flags to be set. +optionsp (IN) - the options flags or value to be set for the given types. +optionslen (IN) - then length of option_value buffer +mode (IN) - for future use (pass 0 for now). +Related Functions +OCILobGetOptions() + +OCILobGetContentType() + +Name +OCI Lob Get Content Type + +Purpose +To get the current contenttype set for the given SecureFile. + +Syntax +sword OCILobGetContentType (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + oratext *contenttypep, + ub4 *contenttypelenp, + ub4 mode); + + +Comments +This function only works on SecureFiles. All others will get an error. +If the securefile does not have a contenttype associated with it, +the contenttype length (= *contenttypelenp) is returned as 0 without +modifying the buffer contenttypep. +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for + diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +contenttypep(IN/OUT)- pointer to the buffer where the contenttype is stored + after successful execution. + The caller needs to allocate the buffer before calling + this function. The size of the allocated buffer should + be >= OCI_LOB_CONTENTTYPE_MAXSIZE bytes +contenttypelenp(IN/OUT)- The caller should set this field to the size + of contenttypep buffer. + After the call successfully executes, it will hold the + size of the contenttype returned. +mode (IN) - for future use (pass 0 for now). +Related Functions +OCISetContentType() + +OCILobSetContentType() + +Name +OCI Lob Set Content Type + +Purpose +To set the contenttype for the given SecureFile Lob. + +Syntax +sword OCILobSetContentType (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + const oratext *contenttypep, + ub4 contenttypelen, + ub4 mode); + + +Comments +This function only works on SecureFiles. All others will get an error. +To clear an existing contenttype set on a securefile, the user will +invoke OCILobSetContentType API with contenttypep set to (oratext *)0, +and contenttypelen set to 0. +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +contenttypep (IN) - the contenttype to be set for the given LOB. +contenttypelen(IN) - the size of contenttype in bytes. The size of the + contenttype should be <= OCI_LOB_CONTENTTYPE_MAXSIZE + bytes. +mode (IN) - for future use (pass 0 for now). +Related Functions +OCILobGetContentType() + + +OCILogoff() +Name +OCI simplified Logoff +Purpose +This function is used to terminate a session created with OCILogon() or +OCILogon2(). +Syntax +sword OCILogoff ( OCISvcCtx *svchp + OCIError *errhp ); +Comments +This call is used to terminate a session which was created with OCILogon() or +OCILogon2(). +This call implicitly deallocates the server, authentication, and service +context handles. +Note: For more information on logging on and off in an application, +refer to the section "Application Initialization, Connection, and +Authorization" on page 2-16. +Parameters +svchp (IN) - the service context handle which was used in the call to +OCILogon() or OCILogon2(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +See Also +OCILogon(), OCILogon2(). + + + + + + +OCILogon() +Name +OCI Service Context Logon +Purpose +This function is used to create a simple logon session. +Syntax +sword OCILogon ( OCIEnv *envhp, + OCIError *errhp, + OCISvcCtx *svchp, + const OraText *username, + ub4 uname_len, + const OraText *password, + ub4 passwd_len, + const OraText *dbname, + ub4 dbname_len ); +Comments +This function is used to create a simple logon session for an application. +Note: Users requiring more complex session (e.g., TP monitor +applications) should refer to the section "Application Initialization, +Connection, and Authorization" on page 2-16. +This call allocates the error and service context handles which are passed to +it. This call also implicitly allocates server and authentication handles +associated with the session. These handles can be retrieved by calling +OCIAttrGet() on the service context handle. +Parameters +envhp (IN) - the OCI environment handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +svchp (OUT) - the service context pointer. +username (IN) - the username. +uname_len (IN) - the length of username. +password (IN) - the user's password. +passwd_len (IN) - the length of password. +dbname (IN) - the name of the database to connect to. +dbname_len (IN) - the length of dbname. +See Also +OCILogoff() + + + + + +OCILogon2() +Name +OCI Service Context Logon +Purpose +This function is used to create a logon session in connection pooling mode. +Syntax +sword OCILogon2 ( OCIEnv *envhp, + OCIError *errhp, + OCISvcCtx **svchp, + const OraText *username, + ub4 uname_len, + const OraText *password, + ub4 passwd_len, + const OraText *dbname, + ub4 dbname_len, + ub4 mode); +Comments +This function is used to create a simple logon session for an application in +Connection Pooling mode. The valid values for mode are currently OCI_POOL and +OCI_DEFAULT. Call to this function with OCI_DEFAULT mode is equivalent to +OCILogon() call. +This call allocates the error and service context handles which are passed to +it. This call also implicitly allocates server and authentication handles +associated with the session. These handles can be retrieved by calling +OCIAttrGet() on the service context handle. This call assumes that +OCIConnectionPoolCreate() has already been called for the same dbname. +Parameters +envhp (IN) - the OCI environment handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +svchp (OUT) - the service context pointer. +username (IN) - the username. +uname_len (IN) - the length of username. +password (IN) - the user's password. If this is null, it is assumed that a + proxy session has to be created and the required grants on + the database are already done. +passwd_len (IN) - the length of password. +dbname (IN) - the name of the database to connect to. +dbname_len (IN) - the length of dbname. +mode (IN) - the mode for doing the server attach. Should be OCI_POOL for + using Connection Pooling. + + +See Also +OCILogoff() + + + + + +OCIMemoryFree() +Name +OCI FREE Memory +Purpose +Frees up storage associated with the pointer. +Syntax +void OCIMemoryFree ( const OCIStmt *stmhp, + void *memptr); +Comments +Frees up dynamically allocated data pointers associated with the pointer using +either the default memory free function or the registered memory free +function, as the case may be. +A user-defined memory free function can be registered during the initial call +to OCIInitialize(). +This call is always successful. +Parameters +stmhp (IN) - statement handle which returned this data buffer. +memptr (IN) - pointer to data allocated by the client library. +Related Functions +OCIInitialize() + + + + + +OCIParamGet() +Name +OCI Get PARaMeter +Purpose +Returns a descriptor of a parameter specified by position in the describe +handle or statement handle. +Syntax +sword OCIParamGet ( const void *hndlp, + ub4 htype, + OCIError *errhp, + void **parmdpp, + ub4 pos ); +Comments +This call returns a descriptor of a parameter specified by position in the +describe handle or statement handle. Parameter descriptors are always +allocated internally by the OCI library. They are read-only. +OCI_NO_DATA may be returned if there are no parameter descriptors for this +position. +See Appendix B for more detailed information about parameter descriptor +attributes. +Parameters +hndlp (IN) - a statement handle or describe handle. The OCIParamGet() +function will return a parameter descriptor for this handle. +htype (IN) - the type of the handle passed in the handle parameter. Valid +types are OCI_HTYPE_DESCRIBE, for a describe handle OCI_HTYPE_STMT, for a +statement handle +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +parmdpp (OUT) - a descriptor of the parameter at the position given in the pos +parameter. +pos (IN) - position number in the statement handle or describe handle. A +parameter descriptor will be returned for this position. +Note: OCI_NO_DATA may be returned if there are no parameter +descriptors for this position. +Related Functions +OCIAttrGet(), OCIAttrSet() + + + + + +OCIParamSet() +Name +OCI Parameter Set in handle +Purpose +Used to set a complex object retrieval descriptor into a complex object +retrieval handle. +Syntax +sword OCIParamGet ( void *hndlp, + ub4 htyp, + OCIError *errhp, + const void *dscp, + ub4 dtyp, + ub4 pos ); +Comments +This call sets a given complex object retrieval descriptor into a complex +object retrieval handle. +The handle must have been previously allocated using OCIHandleAlloc(), and +the descriptor must have been previously allocated using OCIDescAlloc(). +Attributes of the descriptor are set using OCIAttrSet(). +Parameters +hndlp (IN/OUT) - handle pointer. +htype (IN) - handle type. +errhp (IN/OUT) - error handle. +dscp (IN) - complex object retrieval descriptor pointer. +dtyp (IN) - +pos (IN) - position number. +See Also + + + + + +OCIPasswordChange() +Name +OCI Change PassWord +Purpose +This call allows the password of an account to be changed. +Syntax +sword OCIPasswordChange ( OCISvcCtx *svchp, + OCIError *errhp, + const OraText *user_name, + ub4 usernm_len, + const OraText *opasswd, + ub4 opasswd_len, + const OraText *npasswd, + sb4 npasswd_len, + ub4 mode); +Comments +This call allows the password of an account to be changed. This call is +similar to OCISessionBegin() with the following differences: +If the user authentication is already established, it authenticates +the account using the old password and then changes the +password to the new password +If the user authentication is not established, it establishes a user +authentication and authenticates the account using the old +password, then changes the password to the new password. +This call is useful when the password of an account is expired and +OCISessionBegin() returns an error or warning which indicates that the +password has expired. +Parameters +svchp (IN/OUT) - a handle to a service context. The service context handle +must be initialized and have a server context handle associated with it. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +user_name (IN) - specifies the user name. It points to a character string, +whose length is specified in usernm_len. This parameter must be NULL if the +service context has been initialized with an authentication handle. +usernm_len (IN) - the length of the user name string specified in user_name. +For a valid user name string, usernm_len must be non-zero. +opasswd (IN) - specifies the user's old password. It points to a character +string, whose length is specified in opasswd_len . +opasswd_len (IN) - the length of the old password string specified in opasswd. +For a valid password string, opasswd_len must be non-zero. +npasswd (IN) - specifies the user's new password. It points to a character +string, whose length is specified in npasswd_len which must be non-zero for a +valid password string. If the password complexity verification routine is +specified in the user's profile to verify the new password's complexity, the +new password must meet the complexity requirements of the verification +function. +npasswd_len (IN) - then length of the new password string specified in +npasswd. For a valid password string, npasswd_len must be non-zero. +mode - pass as OCI_DEFAULT. +Related Functions +OCISessionBegin() + + +----------------------------------OCIReset------------------------------------ + + +OCIReset() +Name +OCI Reset +Purpose +Resets the interrupted asynchronous operation and protocol. Must be called +if a OCIBreak call had been issued while a non-blocking operation was in +progress. +Syntax +sword OCIReset ( void *hndlp, + OCIError *errhp); +Comments +This call is called in non-blocking mode ONLY. Resets the interrupted +asynchronous operation and protocol. Must be called if a OCIBreak call +had been issued while a non-blocking operation was in progress. +Parameters +hndlp (IN) - the service context handle or the server context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions + + +OCIResultSetToStmt() +Name +OCI convert Result Set to Statement Handle +Purpose +Converts a descriptor to statement handle for fetching rows. +Syntax +sword OCIResultSetToStmt ( OCIResult *rsetdp, + OCIError *errhp ); +Comments +Converts a descriptor to statement handle for fetching rows. +A result set descriptor can be allocated with a call to OCIDescAlloc(). +Parameters +rsetdp (IN/OUT) - a result set descriptor pointer. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions +OCIDescAlloc() + + + + +OCIServerAttach() +Name +OCI ATtaCH to server +Purpose +Creates an access path to a data source for OCI operations. +Syntax +sword OCIServerAttach ( OCIServer *srvhp, + OCIError *errhp, + const OraText *dblink, + sb4 dblink_len, + ub4 mode); +Comments +This call is used to create an association between an OCI application and a +particular server. +This call initializes a server context handle, which must have been previously +allocated with a call to OCIHandleAlloc(). +The server context handle initialized by this call can be associated with a +service context through a call to OCIAttrSet(). Once that association has been +made, OCI operations can be performed against the server. +If an application is operating against multiple servers, multiple server +context handles can be maintained. OCI operations are performed against +whichever server context is currently associated with the service context. +Parameters +srvhp (IN/OUT) - an uninitialized server context handle, which gets +initialized by this call. Passing in an initialized server handle causes an +error. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dblink (IN) - specifies the database (server) to use. This parameter points to +a character string which specifies a connect string or a service point. If the +connect string is NULL, then this call attaches to the default host. The length +of connstr is specified in connstr_len. The connstr pointer may be freed by the +caller on return. +dblink_len (IN) - the length of the string pointed to by connstr. For a valid +connect string name or alias, connstr_len must be non-zero. +mode (IN) - specifies the various modes of operation. For release 8.0, pass as +OCI_DEFAULT - in this mode, calls made to the server on this server context +are made in blocking mode. +Example +See the description of OCIStmtPrepare() on page 13-96 for an example showing +the use of OCIServerAttach(). +Related Functions +OCIServerDetach() + + + +OCIServerDetach() +Name +OCI DeTaCH server +Purpose +Deletes an access to a data source for OCI operations. +Syntax +sword OCIServerDetach ( OCIServer *svrhp, + OCIError *errhp, + ub4 mode); +Comments +This call deletes an access to data source for OCI operations, which was +established by a call to OCIServerAttach(). +Parameters +srvhp (IN) - a handle to an initialized server context, which gets reset to +uninitialized state. The handle is not de-allocated. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +mode (IN) - specifies the various modes of operation. The only valid mode is +OCI_DEFAULT for the default mode. +Related Functions +OCIServerAttach() + + + +OCIServerVersion() +Name +OCI VERSion +Purpose +Returns the version string of the Oracle server. +Syntax +sword OCIServerVersion ( void *hndlp, + OCIError *errhp, + OraText *bufp, + ub4 bufsz + ub1 hndltype ); +Comments +This call returns the version string of the Oracle server. +For example, the following might be returned as the version string if your +application is running against a 7.3.2 server: +Oracle7 Server Release 7.3.2.0.0 - Production Release +PL/SQL Release 2.3.2.0.0 - Production +CORE Version 3.5.2.0.0 - Production +TNS for SEQUENT DYNIX/ptx: Version 2.3.2.0.0 - Production +NLSRTL Version 3.2.2.0.0 - Production + +Parameters +hndlp (IN) - the service context handle or the server context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +bufp (IN) - the buffer in which the version information is returned. +bufsz (IN) - the length of the buffer. +hndltype (IN) - the type of handle passed to the function. +Related Functions + + + + + +OCISessionBegin() +Name +OCI Session Begin and authenticate user +Purpose +Creates a user authentication and begins a user session for a given server. +Syntax +sword OCISessionBegin ( OCISvcCtx *svchp, + OCIError *errhp, + OCISession *usrhp, + ub4 credt, + ub4 mode); + +Comments +For Oracle8, OCISessionBegin() must be called for any given server handle +before requests can be made against it. Also, OCISessionBegin() only supports +authenticating the user for access to the Oracle server specified by the +server handle in the service context. In other words, after OCIServerAttach() +is called to initialize a server handle, OCISessionBegin() must be called to +authenticate the user for that given server. +When OCISessionBegin() is called for the first time for the given server +handle, the initialized authentication handle is called a primary +authentication context. A primary authentication context may not be created +with the OCI_MIGRATE mode. Also, only one primary authentication context can +be created for a given server handle and the primary authentication context c +an only ever be used with that server handle. If the primary authentication +context is set in a service handle with a different server handle, then an +error will result. +After OCISessionBegin() has been called for the server handle, and the primary +authentication context is set in the service handle, OCISessionBegin() may be +called again to initialize another authentication handle with different (or +the same) credentials. When OCISessionBegin() is called with a service handle +set with a primary authentication context, the returned authentication context +in authp is called a user authentication context. As many user authentication +contexts may be initialized as desired. +User authentication contexts may be created with the OCI_MIGRATE mode. +If the OCI_MIGRATE mode is not specified, then the user authentication +context can only ever be used with the same server handle set in svchp. If +OCI_MIGRATE mode is specified, then the user authentication may be set +with different server handles. However, the user authentication context is +restricted to use with only server handles which resolve to the same database +instance and that have equivalent primary authentication contexts. Equivalent +authentication contexts are those which were authenticated as the same +database user. +OCI_SYSDBA, OCI_SYSOPER, OCI_SYSASM, and OCI_PRELIM_AUTH may only be used +with a primary authentication context. +To provide credentials for a call to OCISessionBegin(), one of two methods are +supported. The first is to provide a valid username and password pair for +database authentication in the user authentication handle passed to +OCISessionBegin(). This involves using OCIAttrSet() to set the +OCI_ATTR_USERNAME and OCI_ATTR_PASSWORD attributes on the +authentication handle. Then OCISessionBegin() is called with +OCI_CRED_RDBMS. +Note: When the authentication handle is terminated using +OCISessionEnd(), the username and password attributes remain +unchanged and thus can be re-used in a future call to OCISessionBegin(). +Otherwise, they must be reset to new values before the next +OCISessionBegin() call. +The second type of credentials supported are external credentials. No +attributes need to be set on the authentication handle before calling +OCISessionBegin(). The credential type is OCI_CRED_EXT. This is equivalent +to the Oracle7 `connect /' syntax. If values have been set for +OCI_ATTR_USERNAME and OCI_ATTR_PASSWORD, then these are +ignored if OCI_CRED_EXT is used. +Parameters +svchp (IN) - a handle to a service context. There must be a valid server +handle set in svchp. +errhp (IN) - an error handle to the retrieve diagnostic information. +usrhp (IN/OUT) - a handle to an authentication context, which is initialized +by this call. +credt (IN) - specifies the type of credentials to use for authentication. +Valid values for credt are: +OCI_CRED_RDBMS - authenticate using a database username and +password pair as credentials. The attributes OCI_ATTR_USERNAME +and OCI_ATTR_PASSWORD should be set on the authentication +context before this call. +OCI_CRED_EXT - authenticate using external credentials. No username +or password is provided. +mode (IN) - specifies the various modes of operation. Valid modes are: +OCI_DEFAULT - in this mode, the authentication context returned may +only ever be set with the same server context specified in svchp. This +establishes the primary authentication context. +OCI_MIGRATE - in this mode, the new authentication context may be +set in a service handle with a different server handle. This mode +establishes the user authentication context. +OCI_SYSDBA - in this mode, the user is authenticated for SYSDBA +access. +OCI_SYSOPER - in this mode, the user is authenticated for SYSOPER +access. +OCI_SYSASM - in this mode, the user is authenticated for SYSASM +access. Note that only an ASM instance can grant SYSASM access. +OCI_PRELIM_AUTH - this mode may only be used with OCI_SYSDBA, OCI_SYSASM, +or OCI_SYSOPER to authenticate for certain administration tasks. +Related Functions +OCISessionEnd() + + + + + + +OCISessionEnd() +Name +OCI Terminate user Authentication Context +Purpose +Terminates a user authentication context created by OCISessionBegin() +Syntax +sword OCISessionEnd ( OCISvcCtx *svchp, + OCIError *errhp, + OCISession *usrhp, + ub4 mode); + +Comments +The user security context associated with the service context is invalidated +by this call. Storage for the authentication context is not freed. The +transaction specified by the service context is implicitly committed. The +transaction handle, if explicitly allocated, may be freed if not being used. +Resources allocated on the server for this user are freed. +The authentication handle may be reused in a new call to OCISessionBegin(). +Parameters +svchp (IN/OUT) - the service context handle. There must be a valid server +handle and user authentication handle associated with svchp. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +usrhp (IN) - de-authenticate this user. If this parameter is passed as NULL, +the user in the service context handle is de-authenticated. +mode (IN) - the only valid mode is OCI_DEFAULT. +Example +In this example, an authentication context is destroyed. +Related Functions +OCISessionBegin() + + + + +OCIStmtExecute() +Name +OCI EXECute +Purpose +This call associates an application request with a server. +Syntax +sword OCIStmtExecute ( OCISvcCtx *svchp, + OCIStmt *stmtp, + OCIError *errhp, + ub4 iters, + ub4 rowoff, + const OCISnapshot *snap_in, + OCISnapshot *snap_out, + ub4 mode ); +Comments +This function is used to execute a prepared SQL statement. +Using an execute call, the application associates a request with a server. On +success, OCI_SUCCESS is returned. +If a SELECT statement is executed, the description of the select list follows +implicitly as a response. This description is buffered on the client side for +describes, fetches and define type conversions. Hence it is optimal to +describe a select list only after an execute. +Also for SELECT statements, some results are available implicitly. Rows will +be received and buffered at the end of the execute. For queries with small row +count, a prefetch causes memory to be released in the server if the end of +fetch is reached, an optimization that may result in memory usage reduction. +Set attribute call has been defined to set the number of rows to be prefetched +per result set. +For SELECT statements, at the end of the execute, the statement handle +implicitly maintains a reference to the service context on which it is +executed. It is the user's responsibility to maintain the integrity of the +service context. If the attributes of a service context is changed for +executing some operations on this service context, the service context must +be restored to have the same attributes, that a statement was executed with, +prior to a fetch on the statement handle. The implicit reference is maintained +until the statement handle is freed or the fetch is cancelled or an end of +fetch condition is reached. +Note: If output variables are defined for a SELECT statement before a +call to OCIStmtExecute(), the number of rows specified by iters will be +fetched directly into the defined output buffers and additional rows +equivalent to the prefetch count will be prefetched. If there are no +additional rows, then the fetch is complete without calling +OCIStmtFetch(). +The execute call will return errors if the statement has bind data types that +are not supported in an Oracle7 server. +Parameters +svchp (IN/OUT) - service context handle. +stmtp (IN/OUT) - an statement handle - defines the statement and the +associated data to be executed at the server. It is invalid to pass in a +statement handle that has bind of data types only supported in release 8.0 +when srvchp points to an Oracle7 server. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. If the statement is being +batched and it is successful, then this handle will contain this particular +statement execution specific errors returned from the server when the batch is +flushed. +iters (IN) - the number of times this statement is executed for non-Select +statements. For Select statements, if iters is non-zero, then defines must +have been done for the statement handle. The execution fetches iters rows into +these predefined buffers and prefetches more rows depending upon the prefetch +row count. This function returns an error if iters=0 for non-SELECT +statements. +rowoff (IN) - the index from which the data in an array bind is relevant for +this multiple row execution. +snap_in (IN) - this parameter is optional. if supplied, must point to a +snapshot descriptor of type OCI_DTYPE_SNAP. The contents of this descriptor +must be obtained from the snap_out parameter of a previous call. The +descriptor is ignored if the SQL is not a SELECT. This facility allows +multiple service contexts to ORACLE to see the same consistent snapshot of the +database's committed data. However, uncommitted data in one context is not +visible to another context even using the same snapshot. +snap_out (OUT) - this parameter optional. if supplied, must point to a +descriptor of type OCI_DTYPE_SNAP. This descriptor is filled in with an +opaque representation which is the current ORACLE "system change +number" suitable as a snap_in input to a subsequent call to OCIStmtExecute(). +This descriptor should not be used any longer than necessary in order to avoid +"snapshot too old" errors. +mode (IN) - The modes are: +If OCI_DEFAULT_MODE, the default mode, is selected, the request is +immediately executed. Error handle contains diagnostics on error if any. +OCI_EXACT_FETCH - if the statement is a SQL SELECT, this mode is +only valid if the application has set the prefetch row count prior to this +call. In this mode, the OCI library will get up to the number of rows +specified (i.e., prefetch row count plus iters). If the number of rows +returned by the query is greater than this value, OCI_ERROR will be +returned with ORA-01422 as the implementation specific error in a +diagnostic record. If the number of rows returned by the query is +smaller than the prefetch row count, OCI_SUCCESS_WITH_INFO will +be returned with ORA-01403 as the implementation specific error. The +prefetch buffer size is ignored and the OCI library tries to allocate all the +space required to contain the prefetched rows. The exact fetch semantics +apply to only the top level rows. No more rows can be fetched for this +query at the end of the call. +OCI_KEEP_FETCH_STATE - the result set rows (not yet fetched) of this +statement executed in this transaction will be maintained when the +transaction is detached for migration. By default, a query is cancelled +when a transaction is detached for migration. This mode is the default +mode when connected to a V7 server. +Related Functions +OCIStmtPrepare() + + + + + +OCIStmtFetch() +Name +OCI FetCH +Purpose +Fetches rows from a query. +Syntax +sword OCIStmtFetch ( OCIStmt *stmtp, + OCIError *errhp, + ub4 nrows, + ub2 orientation, + ub4 mode); +Comments +The fetch call is a local call, if prefetched rows suffice. However, this is +transparent to the application. If LOB columns are being read, LOB locators +are fetched for subsequent LOB operations to be performed on these locators. +Prefetching is turned off if LONG columns are involved. +A fetch with nrows set to 0 rows effectively cancels the fetch for this +statement. +Parameters +stmtp (IN) - a statement (application request) handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +nrows (IN) - number of rows to be fetched from the current position. +orientation (IN) - for release 8.0, the only acceptable value is +OCI_FETCH_NEXT, which is also the default value. +mode (IN) - for release 8.0, beta-1, the following mode is defined. +OCI_DEFAULT - default mode +OCI_EOF_FETCH - indicates that it is the last fetch from the result set. +If nrows is non-zero, setting this mode effectively cancels fetching after +retrieving nrows, otherwise it cancels fetching immediately. +Related Functions +OCIAttrGet() + +OCIStmtFetch2() +Name +OCI FetCH2 +Purpose +Fetches rows from a query. +Syntax +sword OCIStmtFetch2 ( OCIStmt *stmtp, + OCIError *errhp, + ub4 nrows, + ub2 orientation, + ub4 scrollOffset, + ub4 mode); +Comments +The fetch call works similar to the OCIStmtFetch call with the +addition of the fetchOffset parameter. It can be used on any +statement handle, whether it is scrollable or not. For a +non-scrollable statement handle, the only acceptable value +will be OCI_FETCH_NEXT, and the fetchOffset parameter will be +ignored. Applications are encouraged to use this new call. + +A fetchOffset with OCI_FETCH_RELATIVE is equivalent to +OCI_FETCH_CURRENT with a value of 0, is equivalent to +OCI_FETCH_NEXT with a value of 1, and equivalent to +OCI_FETCH_PRIOR with a value of -1. Note that the range of +accessible rows is [1,OCI_ATTR_ROW_COUNT] beyond which an +error could be raised if sufficient rows do not exist in + +The fetch call is a local call, if prefetched rows suffice. However, this is +transparent to the application. If LOB columns are being read, LOB locators +are fetched for subsequent LOB operations to be performed on these locators. +Prefetching is turned off if LONG columns are involved. +A fetch with nrows set to 0 rows effectively cancels the fetch for this +statement. +Parameters +stmtp (IN) - a statement (application request) handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +nrows (IN) - number of rows to be fetched from the current position. +It defaults to 1 for orientation OCI_FETCH_LAST. +orientation (IN) - The acceptable values are as follows, with +OCI_FETCH_NEXT being the default value. +OCI_FETCH_CURRENT gets the current row, +OCI_FETCH_NEXT gets the next row from the current position, +OCI_FETCH_FIRST gets the first row in the result set, +OCI_FETCH_LAST gets the last row in the result set, +OCI_FETCH_PRIOR gets the previous row from the current row in the result set, +OCI_FETCH_ABSOLUTE will fetch the row number (specified by fetchOffset +parameter) in the result set using absolute positioning, +OCI_FETCH_RELATIVE will fetch the row number (specified by fetchOffset +parameter) in the result set using relative positioning. +scrollOffset(IN) - offset used with the OCI_FETCH_ABSOLUTE and +OCI_FETCH_RELATIVE orientation parameters only. It specify +the new current position for scrollable result set. It is +ignored for non-scrollable result sets. +mode (IN) - for release 8.0, beta-1, the following mode is defined. +OCI_DEFAULT - default mode +OCI_EOF_FETCH - indicates that it is the last fetch from the result set. +If nrows is non-zero, setting this mode effectively cancels fetching after +retrieving nrows, otherwise it cancels fetching immediately. +Related Functions +OCIAttrGet() + + + +OCIStmtGetPieceInfo() +Name +OCI Get Piece Information +Purpose +Returns piece information for a piecewise operation. +Syntax +sword OCIStmtGetPieceInfo( const OCIStmt *stmtp, + OCIError *errhp, + void **hndlpp, + ub4 *typep, + ub1 *in_outp, + ub4 *iterp, + ub4 *idxp, + ub1 *piecep ); + +Comments +When an execute/fetch call returns OCI_NEED_DATA to get/return a +dynamic bind/define value or piece, OCIStmtGetPieceInfo() returns the +relevant information: bind/define handle, iteration or index number and +which piece. +See the section "Runtime Data Allocation and Piecewise Operations" on page +5-16 for more information about using OCIStmtGetPieceInfo(). +Parameters +stmtp (IN) - the statement when executed returned OCI_NEED_DATA. +errhp (OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +hndlpp (OUT) - returns a pointer to the bind or define handle of the bind or +define whose runtime data is required or is being provided. +typep (OUT) - the type of the handle pointed to by hndlpp: OCI_HTYPE_BIND +(for a bind handle) or OCI_HTYPE_DEFINE (for a define handle). +in_outp (OUT) - returns OCI_PARAM_IN if the data is required for an IN bind +value. Returns OCI_PARAM_OUT if the data is available as an OUT bind +variable or a define position value. +iterp (OUT) - returns the row number of a multiple row operation. +idxp (OUT) - the index of an array element of a PL/SQL array bind operation. +piecep (OUT) - returns one of the following defined values - +OCI_ONE_PIECE, OCI_FIRST_PIECE, OCI_NEXT_PIECE and +OCI_LAST_PIECE. The default value is always OCI_ONE_PIECE. +Related Functions +OCIAttrGet(), OCIAttrGet(), OCIStmtExecute(), OCIStmtFetch(), +OCIStmtSetPieceInfo() + + + + +OCIStmtPrepare() +Name +OCI Statement REQuest +Purpose +This call defines the SQL/PLSQL statement to be executed. +Syntax +sword OCIStmtPrepare ( OCIStmt *stmtp, + OCIError *errhp, + const OraText *stmt, + ub4 stmt_len, + ub4 language, + ub4 mode); +Comments +This call is used to prepare a SQL or PL/SQL statement for execution. The +OCIStmtPrepare() call defines an application request. +This is a purely local call. Data values for this statement initialized in +subsequent bind calls will be stored in a bind handle which will hang off this +statement handle. +This call does not create an association between this statement handle and any +particular server. +See the section "Preparing Statements" on page 2-21 for more information +about using this call. +Parameters +stmtp (IN) - a statement handle. +errhp (IN) - an error handle to retrieve diagnostic information. +stmt (IN) - SQL or PL/SQL statement to be executed. Must be a null-terminated +string. The pointer to the OraText of the statement must be available as long +as the statement is executed. +stmt_len (IN) - length of the statement. Must not be zero. +language (IN) - V7, V8, or native syntax. Possible values are: +OCI_V7_SYNTAX - V7 ORACLE parsing syntax +OCI_V8_SYNTAX - V8 ORACLE parsing syntax +OCI_NTV_SYNTAX - syntax depending upon the version of the server. +mode (IN) - the only defined mode is OCI_DEFAULT for default mode. +Example +This example demonstrates the use of OCIStmtPrepare(), as well as the OCI +application initialization calls. +Related Functions +OCIAttrGet(), OCIStmtExecute() + + +OCIStmtPrepare2() +Name +OCI Statement REQuest with (a) early binding to svchp and/or +(b) stmt caching +Purpose +This call defines the SQL/PLSQL statement to be executed. +Syntax +sword OCIStmtPrepare2 ( OCISvcCtx *svchp, + OCIStmt **stmtp, + OCIError *errhp, + const OraText *stmt, + ub4 stmt_len, + const OraText *key, + ub4 key_len, + ub4 language, + ub4 mode); +Comments +This call is used to prepare a SQL or PL/SQL statement for execution. The +OCIStmtPrepare() call defines an application request. +This is a purely local call. Data values for this statement initialized in +subsequent bind calls will be stored in a bind handle which will hang off this +statement handle. +This call creates an association between the statement handle and a service +context. It differs from OCIStmtPrepare in that respect.It also supports +stmt caching. The stmt will automatically be cached if the authp of the stmt +has enabled stmt caching. +Parameters +svchp (IN) - the service context handle that contains the session that + this stmt handle belongs to. +stmtp (OUT) - an unallocated stmt handle must be pased in. An allocated + and prepared statement handle will be returned. +errhp (IN) - an error handle to retrieve diagnostic information. +stmt (IN) - SQL or PL/SQL statement to be executed. Must be a null- + terminated string. The pointer to the OraText of the statement + must be available as long as the statement is executed. +stmt_len (IN) - length of the statement. Must not be zero. +key (IN) - This is only Valid for OCI Stmt Caching. It indicates the + key to search with. It thus optimizes the search in the cache. +key_len (IN) - the length of the key. This, too, is onlly valid for stmt + caching. +language (IN) - V7, V8, or native syntax. Possible values are: +OCI_V7_SYNTAX - V7 ORACLE parsing syntax +OCI_V8_SYNTAX - V8 ORACLE parsing syntax +OCI_NTV_SYNTAX - syntax depending upon the version of the server. +mode (IN) - the defined modes are OCI_DEFAULT and OCI_PREP2_CACHE_SEARCHONLY. +Example +Related Functions +OCIStmtExecute(), OCIStmtRelease() + + +OCIStmtRelease() +Name +OCI Statement Release. This call is used to relesae the stmt that +was retreived using OCIStmtPrepare2(). If the stmt is release +using this call, OCIHandleFree() must not be called on the stmt +handle. +Purpose +This call releases the statement obtained by OCIStmtPrepare2 +Syntax +sword OCIStmtRelease ( OCIStmt *stmtp, + OCIError *errhp, + cONST OraText *key, + ub4 key_len, + ub4 mode); +Comments +This call is used to release a handle obtained via OCIStmtPrepare2(). +It also frees the memory associated with the handle. +This is a purely local call. +Parameters +stmtp (IN/OUT) - The statement handle to be released/freed. +errhp (IN) - an error handle to retrieve diagnostic information. +key (IN) - This is only Valid for OCI Stmt Caching. It indicates the + key to tag the stmt with. +key_len (IN) - the length of the key. This, too, is only valid for stmt + caching. +mode (IN) - the defined modes are OCI_DEFAULT for default mode and + OCI_STRLS_CACHE_DELETE (only used for Stmt Caching). +Example +Related Functions +OCIStmtExecute(), OCIStmtPrepare2() + + +OCIStmtSetPieceInfo() +Name +OCI Set Piece Information +Purpose +Sets piece information for a piecewise operation. +Syntax +sword OCIStmtSetPieceInfo ( void *hndlp, + ub4 type, + OCIError *errhp, + const void *bufp, + ub4 *alenp, + ub1 piece, + const void *indp, + ub2 *rcodep ); +Comments +When an execute call returns OCI_NEED_DATA to get a dynamic IN/OUT +bind value or piece, OCIStmtSetPieceInfo() sets the piece information: the +buffer, the length, the indicator and which piece is currently being processed. +For more information about using OCIStmtSetPieceInfo() see the section +"Runtime Data Allocation and Piecewise Operations" on page 5-16. +Parameters +hndlp (IN/OUT) - the bind/define handle. +type (IN) - type of the handle. +errhp (OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +bufp (IN/OUT) - bufp is a pointer to a storage containing the data value or +the piece when it is an IN bind variable, otherwise bufp is a pointer to +storage for getting a piece or a value for OUT binds and define variables. For +named data types or REFs, a pointer to the object or REF is returned. +alenp (IN/OUT) - the length of the piece or the value. +piece (IN) - the piece parameter. The following are valid values: +OCI_ONE_PIECE, OCI_FIRST_PIECE, OCI_NEXT_PIECE, or +OCI_LAST_PIECE. +The default value is OCI_ONE_PIECE. This parameter is used for IN bind +variables only. +indp (IN/OUT) - indicator. A pointer to a sb2 value or pointer to an indicator +structure for named data types (SQLT_NTY) and REFs (SQLT_REF), i.e., *indp +is either an sb2 or a void * depending upon the data type. +rcodep (IN/OUT) - return code. +Related Functions +OCIAttrGet(), OCIAttrGet(), OCIStmtExecute(), OCIStmtFetch(), +OCIStmtGetPieceInfo() + + +OCIFormatInit +Name +OCIFormat Package Initialize +Purpose +Initializes the OCIFormat package. +Syntax +sword OCIFormatInit(void *hndl, OCIError *err); +Comments +This routine must be called before calling any other OCIFormat routine. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - OCI environment or session handle +err (IN/OUT) - OCI error handle +Related Functions +OCIFormatTerm() + + +OCIFormatString +Name +OCIFormat Package Format String +Purpose +Writes a text string into the supplied text buffer using the argument +list submitted to it and in accordance with the format string given. +Syntax +sword OCIFormatString(void *hndl, OCIError *err, OraText *buffer, + sbig_ora bufferLength, sbig_ora *returnLength, + const OraText *formatString, ...); +Comments +The first call to this routine must be preceded by a call to the +OCIFormatInit routine that initializes the OCIFormat package +for use. When this routine is no longer needed then terminate +the OCIFormat package by a call to the OCIFormatTerm routine. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - OCI environment or session handle +err (IN/OUT) - OCI error handle +buffer (OUT) - text buffer for the string +bufferLength (IN) - length of the text buffer +returnLength (OUT) - length of the formatted string +formatString (IN) - format specification string +... (IN) - variable argument list +Related Functions + + +OCIFormatTerm +Name +OCIFormat Package Terminate +Purpose +Terminates the OCIFormat package. +Syntax +sword OCIFormatTerm(void *hndl, OCIError *err); +Comments +It must be called after the OCIFormat package is no longer being used. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - OCI environment or session handle +err (IN/OUT) - OCI error handle +Related Functions +OCIFormatInit() + + +OCIFormatTUb1 +Name +OCIFormat Package ub1 Type +Purpose +Return the type value for the ub1 type. +Syntax +sword OCIFormatTUb1(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUb2 +Name +OCIFormat Package ub2 Type +Purpose +Return the type value for the ub2 type. +Syntax +sword OCIFormatTUb2(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUb4 +Name +OCIFormat Package ub4 Type +Purpose +Return the type value for the ub4 type. +Syntax +sword OCIFormatTUb4(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUword +Name +OCIFormat Package uword Type +Purpose +Return the type value for the uword type. +Syntax +sword OCIFormatTUword(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUbig_ora +Name +OCIFormat Package ubig_ora Type +Purpose +Return the type value for the ubig_ora type. +Syntax +sword OCIFormatTUbig_ora(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSb1 +Name +OCIFormat Package sb1 Type +Purpose +Return the type value for the sb1 type. +Syntax +sword OCIFormatTSb1(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSb2 +Name +OCIFormat Package sb2 Type +Purpose +Return the type value for the sb2 type. +Syntax +sword OCIFormatTSb2(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSb4 +Name +OCIFormat Package sb4 Type +Purpose +Return the type value for the sb4 type. +Syntax +sword OCIFormatTSb4(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSword +Name +OCIFormat Package sword Type +Purpose +Return the type value for the sword type. +Syntax +sword OCIFormatTSword(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSbig_ora +Name +OCIFormat Package sbig_ora Type +Purpose +Return the type value for the sbig_ora type. +Syntax +sword OCIFormatTSbig_ora(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEb1 +Name +OCIFormat Package eb1 Type +Purpose +Return the type value for the eb1 type. +Syntax +sword OCIFormatTEb1(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEb2 +Name +OCIFormat Package eb2 Type +Purpose +Return the type value for the eb2 type. +Syntax +sword OCIFormatTEb2(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEb4 +Name +OCIFormat Package eb4 Type +Purpose +Return the type value for the eb4 type. +Syntax +sword OCIFormatTEb4(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEword +Name +OCIFormat Package eword Type +Purpose +Return the type value for the eword type. +Syntax +sword OCIFormatTEword(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTChar +Name +OCIFormat Package text Type +Purpose +Return the type value for the text type. +Syntax +sword OCIFormatTChar(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTText +Name +OCIFormat Package *text Type +Purpose +Return the type value for the *text type. +Syntax +sword OCIFormatTText(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTDouble +Name +OCIFormat Package double Type +Purpose +Return the type value for the double type. +Syntax +sword OCIFormatTDouble(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatDvoid +Name +OCIFormat Package void Type +Purpose +Return the type value for the void type. +Syntax +sword OCIFormatTDvoid(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEnd +Name +OCIFormat Package end Type +Purpose +Return the list terminator's "type". +Syntax +sword OCIFormatTEnd(void); +Comments +None +Parameters +None +Related Functions +None + + +OCISvcCtxToLda() +Name +OCI toggle SerVice context handle to Version 7 Lda_Def +Purpose +Toggles between a V8 service context handle and a V7 Lda_Def. +Syntax +sword OCISvcCtxToLda ( OCISvcCtx *srvhp, + OCIError *errhp, + Lda_Def *ldap ); +Comments +Toggles between an Oracle8 service context handle and an Oracle7 Lda_Def. +This function can only be called after a service context has been properly +initialized. +Once the service context has been translated to an Lda_Def, it can be used in +release 7.x OCI calls (e.g., obindps(), ofen()). +Note: If there are multiple service contexts which share the same server +handle, only one can be in V7 mode at any time. +The action of this call can be reversed by passing the resulting Lda_Def to +the OCILdaToSvcCtx() function. +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +ldap (IN/OUT) - a Logon Data Area for V7-style OCI calls which is initialized +by this call. +Related Functions +OCILdaToSvcCtx() + + + + +OCITransCommit() +Name +OCI TX (transaction) CoMmit +Purpose +Commits the transaction associated with a specified service context. +Syntax +sword OCITransCommit ( OCISvcCtx *srvcp, + OCIError *errhp, + ub4 flags ); +Comments +The transaction currently associated with the service context is committed. If +it is a distributed transaction that the server cannot commit, this call +additionally retrieves the state of the transaction from the database to be +returned to the user in the error handle. +If the application has defined multiple transactions, this function operates +on the transaction currently associated with the service context. If the +application is working with only the implicit local transaction created when +database changes are made, that implicit transaction is committed. +If the application is running in the object mode, then the modified or updated +objects in the object cache for this transaction are also committed. +The flags parameter is used for one-phase commit optimization in distributed +transactions. If the transaction is non-distributed, the flags parameter is +ignored, and OCI_DEFAULT can be passed as its value. OCI applications +managing global transactions should pass a value of +OCI_TRANS_TWOPHASE to the flags parameter for a two-phase commit. The +default is one-phase commit. +Under normal circumstances, OCITransCommit() returns with a status +indicating that the transaction has either been committed or rolled back. With +distributed transactions, it is possible that the transaction is now in-doubt +(i.e., neither committed nor aborted). In this case, OCITransCommit() +attempts to retrieve the status of the transaction from the server. +The status is returned. +Parameters +srvcp (IN) - the service context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags -see the "Comments" section above. +Related Functions +OCITransRollback() + + + + +OCITransDetach() +Name +OCI TX (transaction) DeTach +Purpose +Detaches a transaction. +Syntax +sword OCITransDetach ( OCISvcCtx *srvcp, + OCIError *errhp, + ub4 flags); +Comments +Detaches a global transaction from the service context handle. The transaction +currently attached to the service context handle becomes inactive at the end +of this call. The transaction may be resumed later by calling OCITransStart(), +specifying a flags value of OCI_TRANS_RESUME. +When a transaction is detached, the value which was specified in the timeout +parameter of OCITransStart() when the transaction was started is used to +determine the amount of time the branch can remain inactive before being +deleted by the server's PMON process. +Note: The transaction can be resumed by a different process than the one +that detached it, provided that the transaction has the same +authorization. +Parameters +srvcp (IN) - the service context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags (IN) - you must pass a value of OCI_DEFAULT for this parameter. +Related Functions +OCITransStart() + + + +OCITransForget() +Name +OCI TX (transaction) ForGeT +Purpose +Causes the server to forget a heuristically completed global transaction. +Syntax +sword OCITransForget ( OCISvcCtx *svchp, + OCIError *errhp, + ub4 flags); + +Comments + +Forgets a heuristically completed global transaction. The server deletes the +status of the transaction from the system's pending transaction table. +The XID of the transaction to be forgotten is set as an attribute of the +transaction handle (OCI_ATTR_XID). +Parameters +srvcp (IN) - the service context handle - the transaction is rolled back. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags (IN) - you must pass OCI_DEFAULT for this parameter. +Related Functions +OCITransCommit(), OCITransRollback() + + +OCITransMultiPrepare() +Name +OCI Trans(action) Multi-Branch Prepare +Purpose +Prepares a transaction with multiple branches in a single call. +Syntax +sword OCITransMultiPrepare ( OCISvcCtx *svchp, + ub4 numBranches, + OCITrans **txns, + OCIError **errhp); + +Comments + +Prepares the specified global transaction for commit. +This call is valid only for distributed transactions. +This call is an advanced performance feature intended for use only in +situations where the caller is responsible for preparing all the branches +in a transaction. +Parameters +srvcp (IN) - the service context handle. +numBranches (IN) - This is the number of branches expected. It is also the +array size for the next two parameters. +txns (IN) - This is the array of transaction handles for the branches to +prepare. They should all have the OCI_ATTR_XID set. The global transaction +ID should be the same. +errhp (IN) - This is the array of error handles. If OCI_SUCCESS is not +returned, then these will indicate which branches received which errors. +Related Functions +OCITransPrepare() + + +OCITransPrepare() +Name +OCI TX (transaction) PREpare +Purpose +Prepares a transaction for commit. +Syntax +sword OCITransPrepare ( OCISvcCtx *svchp, + OCIError *errhp, + ub4 flags); + +Comments + +Prepares the specified global transaction for commit. +This call is valid only for distributed transactions. +The call returns OCI_SUCCESS_WITH_INFO if the transaction has not made +any changes. The error handle will indicate that the transaction is read-only. +The flag parameter is not currently used. +Parameters +srvcp (IN) - the service context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags (IN) - you must pass OCI_DEFAULT for this parameter. +Related Functions +OCITransCommit(), OCITransForget() + + + + +OCITransRollback() +Name +OCI TX (transaction) RoLlback +Purpose +Rolls back the current transaction. +Syntax +sword OCITransRollback ( void *svchp, + OCIError *errhp, + ub4 flags ); +Comments +The current transaction- defined as the set of statements executed since the +last OCITransCommit() or since OCISessionBegin()-is rolled back. +If the application is running under object mode then the modified or updated +objects in the object cache for this transaction are also rolled back. +An error is returned if an attempt is made to roll back a global transaction +that is not currently active. +Parameters +svchp (IN) - a service context handle. The transaction currently set in the +service context handle is rolled back. +errhp -(IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags - you must pass a value of OCI_DEFAULT for this parameter. +Related Functions +OCITransCommit() + + + + +OCITransStart() +Name +OCI TX (transaction) STart +Purpose +Sets the beginning of a transaction. +Syntax +sword OCITransStart ( OCISvcCtx *svchp, + OCIError *errhp, + uword timeout, + ub4 flags); + +Comments +This function sets the beginning of a global or serializable transaction. The +transaction context currently associated with the service context handle is +initialized at the end of the call if the flags parameter specifies that a new +transaction should be started. +The XID of the transaction is set as an attribute of the transaction handle +(OCI_ATTR_XID) +Parameters +svchp (IN/OUT) - the service context handle. The transaction context in the +service context handle is initialized at the end of the call if the flag +specified a new transaction to be started. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded in +err and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +timeout (IN) - the time, in seconds, to wait for a transaction to become +available for resumption when OCI_TRANS_RESUME is specified. When +OCI_TRANS_NEW is specified, this value is stored and may be used later by +OCITransDetach(). +flags (IN) - specifies whether a new transaction is being started or an +existing transaction is being resumed. Also specifies serializiability or +read-only status. More than a single value can be specified. By default, +a read/write transaction is started. The flag values are: +OCI_TRANS_NEW - starts a new transaction branch. By default starts a +tightly coupled and migratable branch. +OCI_TRANS_TIGHT - explicitly specifies a tightly coupled branch +OCI_TRANS_LOOSE - specifies a loosely coupled branch +OCI_TRANS_RESUME - resumes an existing transaction branch. +OCI_TRANS_READONLY - start a readonly transaction +OCI_TRANS_SERIALIZABLE - start a serializable transaction +Related Functions +OCITransDetach() + + + + + +******************************************************************************/ +/*-----------------------Dynamic Callback Function Pointers------------------*/ + + +typedef sb4 (*OCICallbackInBind)(void *ictxp, OCIBind *bindp, ub4 iter, + ub4 index, void **bufpp, ub4 *alenp, + ub1 *piecep, void **indp); + +typedef sb4 (*OCICallbackOutBind)(void *octxp, OCIBind *bindp, ub4 iter, + ub4 index, void **bufpp, ub4 **alenp, + ub1 *piecep, void **indp, + ub2 **rcodep); + +typedef sb4 (*OCICallbackDefine)(void *octxp, OCIDefine *defnp, ub4 iter, + void **bufpp, ub4 **alenp, ub1 *piecep, + void **indp, ub2 **rcodep); + +typedef sword (*OCIUserCallback)(void *ctxp, void *hndlp, ub4 type, + ub4 fcode, ub4 when, sword returnCode, + sb4 *errnop, va_list arglist); + +typedef sword (*OCIEnvCallbackType)(OCIEnv *env, ub4 mode, + size_t xtramem_sz, void *usrmemp, + OCIUcb *ucbDesc); + +typedef sb4 (*OCICallbackLobRead)(void *ctxp, const void *bufp, + ub4 len, ub1 piece); + +typedef sb4 (*OCICallbackLobWrite)(void *ctxp, void *bufp, + ub4 *lenp, ub1 *piece); + +#ifdef ORAXB8_DEFINED + +typedef sb4 (*OCICallbackLobRead2)(void *ctxp, const void *bufp, oraub8 len, + ub1 piece, void **changed_bufpp, + oraub8 *changed_lenp); + +typedef sb4 (*OCICallbackLobWrite2)(void *ctxp, void *bufp, oraub8 *lenp, + ub1 *piece, void **changed_bufpp, + oraub8 *changed_lenp); + +typedef sb4 (*OCICallbackLobArrayRead)(void *ctxp, ub4 array_iter, + const void *bufp, oraub8 len, + ub1 piece, void **changed_bufpp, + oraub8 *changed_lenp); + +typedef sb4 (*OCICallbackLobArrayWrite)(void *ctxp, ub4 array_iter, + void *bufp, oraub8 *lenp, + ub1 *piece, void **changed_bufpp, + oraub8 *changed_lenp); +#endif + +typedef sb4 (*OCICallbackLobGetDeduplicateRegions)(void *ctxp, + OCILobRegion *regions, + ub4 count, ub1 piece, + OCILobRegion **changed_reg, + ub4 *changed_count); + +typedef sb4 (*OCICallbackAQEnq)(void *ctxp, void **payload, + void **payload_ind); + +typedef sb4 (*OCICallbackAQEnqStreaming)(void *ctxp, void **payload, + void **payload_ind, + OCIAQMsgProperties **msgprop, + OCIType **tdo); + +typedef sb4 (*OCICallbackAQDeq)(void *ctxp, void **payload, + void **payload_ind); + +/*--------------------------Failover Callback Structure ---------------------*/ +typedef sb4 (*OCICallbackFailover)(void *svcctx, void *envctx, + void *fo_ctx, ub4 fo_type, + ub4 fo_event); + +typedef struct +{ + OCICallbackFailover callback_function; + void *fo_ctx; +} +OCIFocbkStruct; + +/*---------------------Statement Cache callback function ------------------*/ + +typedef sword (*OCICallbackStmtCache)(void *ctx, OCIStmt *stmt, ub4 mode); + +/*--------------------------HA Callback Structure ---------------------*/ +typedef void (*OCIEventCallback)(void *evtctx, OCIEvent *eventhp); + + +/***************************************************************************** + ACTUAL PROTOTYPE DECLARATIONS +******************************************************************************/ + +sword OCIInitialize (ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr) ); + +sword OCITerminate( ub4 mode); + +sword OCIEnvCreate (OCIEnv **envp, ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr), + size_t xtramem_sz, void **usrmempp); + +sword OCIEnvNlsCreate (OCIEnv **envp, ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr), + size_t xtramem_sz, void **usrmempp, + ub2 charset, ub2 ncharset); + +sword OCIFEnvCreate (OCIEnv **envp, ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr), + size_t xtramem_sz, void **usrmempp, void *fupg); + +sword OCIHandleAlloc(const void *parenth, void **hndlpp, const ub4 type, + const size_t xtramem_sz, void **usrmempp); + +sword OCIHandleFree(void *hndlp, const ub4 type); + + +sword OCIDescriptorAlloc(const void *parenth, void **descpp, + const ub4 type, const size_t xtramem_sz, + void **usrmempp); + +sword OCIArrayDescriptorAlloc(const void *parenth, void **descpp, + const ub4 type, ub4 array_size, + const size_t xtramem_sz, void **usrmempp); + +sword OCIDescriptorFree(void *descp, const ub4 type); + +sword OCIArrayDescriptorFree(void **descp, const ub4 type); + +sword OCIEnvInit (OCIEnv **envp, ub4 mode, + size_t xtramem_sz, void **usrmempp); + +sword OCIServerAttach (OCIServer *srvhp, OCIError *errhp, + const OraText *dblink, sb4 dblink_len, ub4 mode); + +sword OCIServerDetach (OCIServer *srvhp, OCIError *errhp, ub4 mode); + +sword OCISessionBegin (OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, + ub4 credt, ub4 mode); + +sword OCISessionEnd (OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, + ub4 mode); + +sword OCILogon (OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + const OraText *username, ub4 uname_len, + const OraText *password, ub4 passwd_len, + const OraText *dbname, ub4 dbname_len); + +sword OCILogon2 (OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + const OraText *username, ub4 uname_len, + const OraText *password, ub4 passwd_len, + const OraText *dbname, ub4 dbname_len, + ub4 mode); + +sword OCILogoff (OCISvcCtx *svchp, OCIError *errhp); + + +sword OCIPasswordChange (OCISvcCtx *svchp, OCIError *errhp, + const OraText *user_name, ub4 usernm_len, + const OraText *opasswd, ub4 opasswd_len, + const OraText *npasswd, ub4 npasswd_len, + ub4 mode); + +sword OCIStmtPrepare (OCIStmt *stmtp, OCIError *errhp, const OraText *stmt, + ub4 stmt_len, ub4 language, ub4 mode); + +sword OCIStmtPrepare2 ( OCISvcCtx *svchp, OCIStmt **stmtp, OCIError *errhp, + const OraText *stmt, ub4 stmt_len, const OraText *key, + ub4 key_len, ub4 language, ub4 mode); + +sword OCIStmtRelease ( OCIStmt *stmtp, OCIError *errhp, const OraText *key, + ub4 key_len, ub4 mode); + +sword OCIBindByPos (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, + ub2 dty, void *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + +sword OCIBindByName (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, + const OraText *placeholder, sb4 placeh_len, + void *valuep, sb4 value_sz, ub2 dty, + void *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + +sword OCIBindObject (OCIBind *bindp, OCIError *errhp, const OCIType *type, + void **pgvpp, ub4 *pvszsp, void **indpp, + ub4 *indszp); + +sword OCIBindDynamic (OCIBind *bindp, OCIError *errhp, void *ictxp, + OCICallbackInBind icbfp, void *octxp, + OCICallbackOutBind ocbfp); + +sword OCIBindArrayOfStruct (OCIBind *bindp, OCIError *errhp, + ub4 pvskip, ub4 indskip, + ub4 alskip, ub4 rcskip); + +sword OCIStmtGetPieceInfo (OCIStmt *stmtp, OCIError *errhp, + void **hndlpp, ub4 *typep, + ub1 *in_outp, ub4 *iterp, ub4 *idxp, + ub1 *piecep); + +sword OCIStmtSetPieceInfo (void *hndlp, ub4 type, OCIError *errhp, + const void *bufp, ub4 *alenp, ub1 piece, + const void *indp, ub2 *rcodep); + +sword OCIStmtExecute (OCISvcCtx *svchp, OCIStmt *stmtp, OCIError *errhp, + ub4 iters, ub4 rowoff, const OCISnapshot *snap_in, + OCISnapshot *snap_out, ub4 mode); + +sword OCIDefineByPos (OCIStmt *stmtp, OCIDefine **defnp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, ub2 dty, + void *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode); + +sword OCIDefineObject (OCIDefine *defnp, OCIError *errhp, + const OCIType *type, void **pgvpp, + ub4 *pvszsp, void **indpp, ub4 *indszp); + +sword OCIDefineDynamic (OCIDefine *defnp, OCIError *errhp, void *octxp, + OCICallbackDefine ocbfp); + +sword OCIRowidToChar (OCIRowid *rowidDesc, OraText *outbfp, ub2 *outbflp, + OCIError *errhp); + +sword OCIDefineArrayOfStruct (OCIDefine *defnp, OCIError *errhp, ub4 pvskip, + ub4 indskip, ub4 rlskip, ub4 rcskip); + +sword OCIStmtFetch (OCIStmt *stmtp, OCIError *errhp, ub4 nrows, + ub2 orientation, ub4 mode); + +sword OCIStmtFetch2 (OCIStmt *stmtp, OCIError *errhp, ub4 nrows, + ub2 orientation, sb4 scrollOffset, ub4 mode); + +sword OCIStmtGetBindInfo (OCIStmt *stmtp, OCIError *errhp, ub4 size, + ub4 startloc, + sb4 *found, OraText *bvnp[], ub1 bvnl[], + OraText *invp[], ub1 inpl[], ub1 dupl[], + OCIBind **hndl); + +sword OCIDescribeAny (OCISvcCtx *svchp, OCIError *errhp, + void *objptr, + ub4 objnm_len, ub1 objptr_typ, ub1 info_level, + ub1 objtyp, OCIDescribe *dschp); + +sword OCIParamGet (const void *hndlp, ub4 htype, OCIError *errhp, + void **parmdpp, ub4 pos); + +sword OCIParamSet(void *hdlp, ub4 htyp, OCIError *errhp, const void *dscp, + ub4 dtyp, ub4 pos); + +sword OCITransStart (OCISvcCtx *svchp, OCIError *errhp, + uword timeout, ub4 flags ); + +sword OCITransDetach (OCISvcCtx *svchp, OCIError *errhp, ub4 flags ); + +sword OCITransCommit (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCITransRollback (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCITransPrepare (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCITransMultiPrepare (OCISvcCtx *svchp, ub4 numBranches, + OCITrans **txns, OCIError **errhp); + +sword OCITransForget (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCIErrorGet (void *hndlp, ub4 recordno, OraText *sqlstate, + sb4 *errcodep, OraText *bufp, ub4 bufsiz, ub4 type); + +sword OCILobAppend (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp); + +sword OCILobAssign (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp); + +sword OCILobCharSetForm (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *locp, ub1 *csfrm); + +sword OCILobCharSetId (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *locp, ub2 *csid); + +sword OCILobCopy (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *dst_locp, + OCILobLocator *src_locp, ub4 amount, ub4 dst_offset, + ub4 src_offset); + +sword OCILobCreateTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub2 csid, + ub1 csfrm, + ub1 lobtype, + boolean cache, + OCIDuration duration); + + +sword OCILobClose( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp ); + + +sword OCILobDisableBuffering (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +sword OCILobEnableBuffering (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +sword OCILobErase (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amount, ub4 offset); + +sword OCILobFileClose (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep); + +sword OCILobFileCloseAll (OCISvcCtx *svchp, OCIError *errhp); + +sword OCILobFileExists (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + boolean *flag); + +sword OCILobFileGetName (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *filep, + OraText *dir_alias, ub2 *d_length, + OraText *filename, ub2 *f_length); + +sword OCILobFileIsOpen (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + boolean *flag); + +sword OCILobFileOpen (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + ub1 mode); + +sword OCILobFileSetName (OCIEnv *envhp, OCIError *errhp, + OCILobLocator **filepp, + const OraText *dir_alias, ub2 d_length, + const OraText *filename, ub2 f_length); + +sword OCILobFlushBuffer (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 flag); + +sword OCILobFreeTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +sword OCILobGetChunkSize(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *chunksizep); + +sword OCILobGetLength (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, + ub4 *lenp); + +sword OCILobIsEqual (OCIEnv *envhp, const OCILobLocator *x, + const OCILobLocator *y, + boolean *is_equal); + +sword OCILobIsOpen( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + boolean *flag); + +sword OCILobIsTemporary(OCIEnv *envp, + OCIError *errhp, + OCILobLocator *locp, + boolean *is_temporary); + +sword OCILobLoadFromFile (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + ub4 amount, ub4 dst_offset, + ub4 src_offset); + +sword OCILobLocatorAssign (OCISvcCtx *svchp, OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp); + + +sword OCILobLocatorIsInit (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *locp, + boolean *is_initialized); + +sword OCILobOpen( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub1 mode ); + +sword OCILobRead (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amtp, ub4 offset, void *bufp, ub4 bufl, void *ctxp, + OCICallbackLobRead cbfp, ub2 csid, ub1 csfrm); + +sword OCILobTrim (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 newlen); + +sword OCILobWrite (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amtp, ub4 offset, void *bufp, ub4 buflen, + ub1 piece, void *ctxp, OCICallbackLobWrite cbfp, + ub2 csid, ub1 csfrm); + +sword OCILobGetDeduplicateRegions(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, + OCILobRegion *regp, ub4 *count, ub1 piece, + void *ctxp, + OCICallbackLobGetDeduplicateRegions cbfp); + +sword OCILobWriteAppend(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *lobp, + ub4 *amtp, void *bufp, ub4 bufl, ub1 piece, + void *ctxp, OCICallbackLobWrite cbfp, ub2 csid, + ub1 csfrm); + +sword OCIBreak (void *hndlp, OCIError *errhp); + +sword OCIReset (void *hndlp, OCIError *errhp); + +sword OCIServerVersion (void *hndlp, OCIError *errhp, OraText *bufp, + ub4 bufsz, + ub1 hndltype); + +sword OCIServerRelease (void *hndlp, OCIError *errhp, OraText *bufp, + ub4 bufsz, + ub1 hndltype, ub4 *version); + +sword OCIAttrGet (const void *trgthndlp, ub4 trghndltyp, + void *attributep, ub4 *sizep, ub4 attrtype, + OCIError *errhp); + +sword OCIAttrSet (void *trgthndlp, ub4 trghndltyp, void *attributep, + ub4 size, ub4 attrtype, OCIError *errhp); + +sword OCISvcCtxToLda (OCISvcCtx *svchp, OCIError *errhp, Lda_Def *ldap); + +sword OCILdaToSvcCtx (OCISvcCtx **svchpp, OCIError *errhp, Lda_Def *ldap); + +sword OCIResultSetToStmt (OCIResult *rsetdp, OCIError *errhp); + +sword OCIFileClose ( void *hndl, OCIError *err, OCIFileObject *filep ); + +sword OCIUserCallbackRegister(void *hndlp, ub4 type, void *ehndlp, + OCIUserCallback callback, void *ctxp, + ub4 fcode, ub4 when, OCIUcb *ucbDesc); + +sword OCIUserCallbackGet(void *hndlp, ub4 type, void *ehndlp, + ub4 fcode, ub4 when, OCIUserCallback *callbackp, + void **ctxpp, OCIUcb *ucbDesc); + +sword OCISharedLibInit(void *metaCtx, void *libCtx, ub4 argfmt, sword argc, + void **argv, OCIEnvCallbackType envCallback); + +sword OCIFileExists ( void *hndl, OCIError *err, OraText *filename, + OraText *path, ub1 *flag ); + +sword OCIFileFlush( void *hndl, OCIError *err, OCIFileObject *filep ); + + +sword OCIFileGetLength( void *hndl, OCIError *err, OraText *filename, + OraText *path, ubig_ora *lenp ); + +sword OCIFileInit ( void *hndl, OCIError *err ); + +sword OCIFileOpen ( void *hndl, OCIError *err, OCIFileObject **filep, + OraText *filename, OraText *path, ub4 mode, ub4 create, + ub4 type ); + +sword OCIFileRead ( void *hndl, OCIError *err, OCIFileObject *filep, + void *bufp, ub4 bufl, ub4 *bytesread ); + +sword OCIFileSeek ( void *hndl, OCIError *err, OCIFileObject *filep, + uword origin, ubig_ora offset, sb1 dir ); + +sword OCIFileTerm ( void *hndl, OCIError *err ); + + +sword OCIFileWrite ( void *hndl, OCIError *err, OCIFileObject *filep, + void *bufp, ub4 buflen, ub4 *byteswritten ); + + +#ifdef ORAXB8_DEFINED + +sword OCILobCopy2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp, oraub8 amount, + oraub8 dst_offset, + oraub8 src_offset); + +sword OCILobErase2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *amount, oraub8 offset); + +sword OCILobGetLength2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, oraub8 *lenp); + +sword OCILobLoadFromFile2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + oraub8 amount, oraub8 dst_offset, + oraub8 src_offset); + +sword OCILobRead2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *byte_amtp, oraub8 *char_amtp, oraub8 offset, + void *bufp, oraub8 bufl, ub1 piece, void *ctxp, + OCICallbackLobRead2 cbfp, ub2 csid, ub1 csfrm); + +sword OCILobArrayRead (OCISvcCtx *svchp, OCIError *errhp, ub4 *array_iter, + OCILobLocator **lobp_arr, oraub8 *byte_amt_arr, + oraub8 *char_amt_arr, oraub8 *offset_arr, + void **bufp_arr, oraub8 *bufl_arr, ub1 piece, + void *ctxp, OCICallbackLobArrayRead cbfp, ub2 csid, + ub1 csfrm); + +sword OCILobTrim2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 newlen); + +sword OCILobWrite2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *byte_amtp, oraub8 *char_amtp, oraub8 offset, + void *bufp, oraub8 buflen, ub1 piece, void *ctxp, + OCICallbackLobWrite2 cbfp, ub2 csid, ub1 csfrm); + +sword OCILobArrayWrite (OCISvcCtx *svchp, OCIError *errhp, ub4 *array_iter, + OCILobLocator **lobp_arr, oraub8 *byte_amt_arr, + oraub8 *char_amt_arr, oraub8 *offset_arr, + void **bufp_arr, oraub8 *bufl_arr, ub1 piece, + void *ctxp, OCICallbackLobArrayWrite cbfp, ub2 csid, + ub1 csfrm); + +sword OCILobWriteAppend2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, + oraub8 *byte_amtp, oraub8 *char_amtp, void *bufp, + oraub8 bufl, ub1 piece, void *ctxp, + OCICallbackLobWrite2 cbfp, ub2 csid, ub1 csfrm); + +sword OCILobGetStorageLimit (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, oraub8 *limitp); + +sword OCILobGetOptions (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, + ub4 optypes, void *optionsp, ub4 *optionslenp, + ub4 mode); + +sword OCILobSetOptions (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, + ub4 optypes, void *optionsp, ub4 optionslen, + ub4 mode); + +sword OCILobGetContentType (OCISvcCtx *svchp, + OCIError *errhp, OCILobLocator *lobp, + oratext *contenttypep, ub4 *contenttypelenp, + ub4 mode); + +sword OCILobSetContentType (OCISvcCtx *svchp, + OCIError *errhp, OCILobLocator *lobp, + const oratext *contenttypep, ub4 contenttypelen, + ub4 mode); + +#endif + +/* + ** Initialize the security package + */ +sword OCISecurityInitialize (OCISecurity *sechandle, OCIError *error_handle); + +sword OCISecurityTerminate (OCISecurity *sechandle, OCIError *error_handle); + +sword OCISecurityOpenWallet(OCISecurity *osshandle, + OCIError *error_handle, + size_t wrllen, + OraText *wallet_resource_locator, + size_t pwdlen, + OraText *password, + nzttWallet *wallet); + +sword OCISecurityCloseWallet(OCISecurity *osshandle, + OCIError *error_handle, + nzttWallet *wallet); + +sword OCISecurityCreateWallet(OCISecurity *osshandle, + OCIError *error_handle, + size_t wrllen, + OraText *wallet_resource_locator, + size_t pwdlen, + OraText *password, + nzttWallet *wallet); + +sword OCISecurityDestroyWallet(OCISecurity *osshandle, + OCIError *error_handle, + size_t wrllen, + OraText *wallet_resource_locator, + size_t pwdlen, + OraText *password); + +sword OCISecurityStorePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona **persona, + nzttWallet *wallet); + +sword OCISecurityOpenPersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona); + +sword OCISecurityClosePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona); + +sword OCISecurityRemovePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona **persona); + +sword OCISecurityCreatePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentType identity_type, + nzttCipherType cipher_type, + nzttPersonaDesc *desc, + nzttPersona **persona); + +sword OCISecuritySetProtection(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttcef crypto_engine_function, + nztttdufmt data_unit_format, + nzttProtInfo *protection_info); + +sword OCISecurityGetProtection(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttcef crypto_engine_function, + nztttdufmt * data_unit_format_ptr, + nzttProtInfo *protection_info); + +sword OCISecurityRemoveIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr); + +sword OCISecurityCreateIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentType type, + nzttIdentityDesc *desc, + nzttIdentity **identity_ptr); + +sword OCISecurityAbortIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr); + +sword OCISecurityFreeIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr); + + +sword OCISecurityStoreTrustedIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr, + nzttPersona *persona); + +sword OCISecuritySign(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *buffer_block); + +sword OCISecuritySignExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t inputlen, + size_t *signature_length); + +sword OCISecurityVerify(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t siglen, + ub1 *signature, + nzttBufferBlock *extracted_message, + boolean *verified, + boolean *validated, + nzttIdentity **signing_party_identity); + +sword OCISecurityValidate(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttIdentity *identity, + boolean *validated); + +sword OCISecuritySignDetached(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t input_length, + ub1 * input, + nzttBufferBlock *signature); + +sword OCISecuritySignDetExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *required_buffer_length); + +sword OCISecurityVerifyDetached(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t data_length, + ub1 *data, + size_t siglen, + ub1 *signature, + boolean *verified, + boolean *validated, + nzttIdentity **signing_party_identity); + +sword OCISecurity_PKEncrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_of_recipients, + nzttIdentity *recipient_list, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *encrypted_data); + +sword OCISecurityPKEncryptExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_recipients, + size_t input_length, + size_t *buffer_length_required); + +sword OCISecurityPKDecrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *encrypted_data); + +sword OCISecurityEncrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *encrypted_data); + +sword OCISecurityEncryptExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *encrypted_data_length); + +sword OCISecurityDecrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces decryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *decrypted_data); + +sword OCISecurityEnvelope(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_of_recipients, + nzttIdentity *identity, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *enveloped_data); + +sword OCISecurityDeEnvelope(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces decryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *output_message, + boolean *verified, + boolean *validated, + nzttIdentity **sender_identity); + +sword OCISecurityKeyedHash(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces hash_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *keyed_hash); + +sword OCISecurityKeyedHashExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *required_buffer_length); + +sword OCISecurityHash(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces hash_state, + size_t input, + ub1 *input_length, + nzttBufferBlock *hash); + +sword OCISecurityHashExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *required_buffer_length); + +sword OCISecuritySeedRandom(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t seed_length, + ub1 *seed); + +sword OCISecurityRandomBytes(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_of_bytes_desired, + nzttBufferBlock *random_bytes); + +sword OCISecurityRandomNumber(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + uword *random_number_ptr); + +sword OCISecurityInitBlock(OCISecurity *osshandle, + OCIError *error_handle, + nzttBufferBlock *buffer_block); + +sword OCISecurityReuseBlock(OCISecurity *osshandle, + OCIError *error_handle, + nzttBufferBlock *buffer_block); + +sword OCISecurityPurgeBlock(OCISecurity *osshandle, + OCIError *error_handle, + nzttBufferBlock *buffer_block); + +sword OCISecuritySetBlock(OCISecurity *osshandle, + OCIError *error_handle, + uword flags_to_set, + size_t buffer_length, + size_t used_buffer_length, + ub1 *buffer, + nzttBufferBlock *buffer_block); + +sword OCISecurityGetIdentity(OCISecurity *osshandle, + OCIError *error_handle, + size_t namelen, + OraText *distinguished_name, + nzttIdentity **identity); + +sword OCIAQEnq(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, OCIAQMsgProperties *msgprop, + OCIType *payload_tdo, void **payload, void **payload_ind, + OCIRaw **msgid, ub4 flags); + +sword OCIAQDeq(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQDeqOptions *deqopt, OCIAQMsgProperties *msgprop, + OCIType *payload_tdo, void **payload, void **payload_ind, + OCIRaw **msgid, ub4 flags); + +sword OCIAQEnqArray(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, ub4 *iters, + OCIAQMsgProperties **msgprop, OCIType *payload_tdo, + void **payload, void **payload_ind, OCIRaw **msgid, + void *ctxp, OCICallbackAQEnq enqcbfp, ub4 flags); + +sword OCIAQEnqStreaming(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, OCIType *payload_tdo, + void *ctxp, OCICallbackAQEnqStreaming enqcbfp, + ub4 flags); + +sword OCIAQDeqArray(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQDeqOptions *deqopt, ub4 *iters, + OCIAQMsgProperties **msgprop, OCIType *payload_tdo, + void **payload, void **payload_ind, OCIRaw **msgid, + void *ctxp, OCICallbackAQDeq deqcbfp, ub4 flags); + +sword OCIAQListen(OCISvcCtx *svchp, OCIError *errhp, + OCIAQAgent **agent_list, ub4 num_agents, + sb4 wait, OCIAQAgent **agent, + ub4 flags); + +sword OCIAQListen2(OCISvcCtx *svchp, OCIError *errhp, + OCIAQAgent **agent_list, ub4 num_agents, + OCIAQListenOpts *lopts, OCIAQAgent **agent, + OCIAQLisMsgProps *lmops, ub4 flags); + +sword OCIAQGetReplayInfo(OCISvcCtx *svchp, OCIError *errhp, + OraText *queue_name, OCIAQAgent *sender, + ub4 replay_attribute, OraText *correlation, + ub2 *corr_len); + +sword OCIAQResetReplayInfo(OCISvcCtx *svchp, OCIError *errhp, + OraText *queue_name, OCIAQAgent *sender, + ub4 replay_attribute); + +sword OCIExtractInit(void *hndl, OCIError *err); + +sword OCIExtractTerm(void *hndl, OCIError *err); + +sword OCIExtractReset(void *hndl, OCIError *err); + +sword OCIExtractSetNumKeys(void *hndl, OCIError *err, uword numkeys); + +sword OCIExtractSetKey(void *hndl, OCIError *err, const OraText *name, + ub1 type, ub4 flag, const void *defval, + const sb4 *intrange, const OraText *const *strlist); + +sword OCIExtractFromFile(void *hndl, OCIError *err, ub4 flag, + OraText *filename); + +sword OCIExtractFromStr(void *hndl, OCIError *err, ub4 flag, OraText *input); + +sword OCIExtractToInt(void *hndl, OCIError *err, OraText *keyname, + uword valno, sb4 *retval); + +sword OCIExtractToBool(void *hndl, OCIError *err, OraText *keyname, + uword valno, ub1 *retval); + +sword OCIExtractToStr(void *hndl, OCIError *err, OraText *keyname, + uword valno, OraText *retval, uword buflen); + +sword OCIExtractToOCINum(void *hndl, OCIError *err, OraText *keyname, + uword valno, OCINumber *retval); + +sword OCIExtractToList(void *hndl, OCIError *err, uword *numkeys); + +sword OCIExtractFromList(void *hndl, OCIError *err, uword index, + OraText **name, + ub1 *type, uword *numvals, void ***values); + +/* Memory Related Service Interfaces */ + +sword OCIMemoryAlloc(void *hdl, OCIError *err, void **mem, + OCIDuration dur, ub4 size, ub4 flags); + +sword OCIMemoryResize(void *hdl, OCIError *err, void **mem, + ub4 newsize, ub4 flags); + +sword OCIMemoryFree(void *hdl, OCIError *err, void *mem); + +sword OCIContextSetValue(void *hdl, OCIError *err, OCIDuration duration, + ub1 *key, ub1 keylen, void *ctx_value); + +sword OCIContextGetValue(void *hdl, OCIError *err, ub1 *key, + ub1 keylen, void **ctx_value); + +sword OCIContextClearValue(void *hdl, OCIError *err, ub1 *key, + ub1 keylen); + +sword OCIContextGenerateKey(void *hdl, OCIError *err, ub4 *key); + +sword OCIMemorySetCurrentIDs(void *hdl, OCIError *err, + ub4 curr_session_id, ub4 curr_trans_id, + ub4 curr_stmt_id); + +sword OCIPicklerTdsCtxInit(OCIEnv *env, OCIError *err, + OCIPicklerTdsCtx **tdsc); + +sword OCIPicklerTdsCtxFree(OCIEnv *env, OCIError *err, OCIPicklerTdsCtx *tdsc); + +sword OCIPicklerTdsInit(OCIEnv *env, OCIError *err, OCIPicklerTdsCtx *tdsc, + OCIPicklerTds **tdsh); + +sword OCIPicklerTdsFree(OCIEnv *env, OCIError *err, OCIPicklerTds *tdsh); + +sword OCIPicklerTdsCreateElementNumber(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub1 prec, + sb1 scale, OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElementChar(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub2 len, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElementVarchar(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub2 len, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElementRaw(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub2 len, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElement(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, OCITypeCode dty, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsAddAttr(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, OCIPicklerTdsElement elt); + +sword OCIPicklerTdsGenerate(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh); + +sword OCIPicklerTdsGetAttr(OCIEnv *env, OCIError *err, + const OCIPicklerTds *tdsh, ub1 attrno, + OCITypeCode *typ, ub2 *len); + +sword OCIPicklerFdoInit(OCIEnv *env, OCIError *err, + OCIPicklerFdo **fdoh); + +sword OCIPicklerFdoFree(OCIEnv *env, OCIError *err, + OCIPicklerFdo *fdoh); + +sword OCIPicklerImageInit(OCIEnv *env, OCIError *err, + OCIPicklerFdo *fdoh, + OCIPicklerTds *tdsh, + OCIPicklerImage **imgh); + +sword OCIPicklerImageFree(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +sword OCIPicklerImageAddScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, + void *scalar, ub4 len); + +sword OCIPicklerImageAddNullScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +sword OCIPicklerImageGenerate(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +sword OCIPicklerImageGetScalarSize(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, + ub4 attrno, ub4 *size); + +sword OCIPicklerImageGetScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, ub4 attrno, + void *buf, ub4 *len, OCIInd *ind); + +sword OCIPicklerImageCollBegin(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, const OCIPicklerTds *colltdsh); + +sword OCIPicklerImageCollAddScalar( OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, void *scalar, + ub4 buflen, OCIInd ind); + +sword OCIPicklerImageCollEnd(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +/* should take svcctx for locator stuff */ +sword OCIPicklerImageCollBeginScan(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, const OCIPicklerTds *coll_tdsh, + ub4 attrnum, ub4 startidx, OCIInd *ind); + +sword OCIPicklerImageCollGetScalarSize(OCIEnv *env, OCIError *err, + const OCIPicklerTds *coll_tdsh, ub4 *size); + +sword OCIPicklerImageCollGetScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, void *buf, + ub4 *buflen, OCIInd *ind); + +sword OCIAnyDataGetType(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode *tc, OCIType **type); + +sword OCIAnyDataIsNull(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + boolean *isnull); + +sword OCIAnyDataConvert(OCISvcCtx *svchp, OCIError *errhp, OCITypeCode tc, + OCIType *type, OCIDuration dur, void *ind, void *data_val, + ub4 len, OCIAnyData **sdata); + +sword OCIAnyDataBeginCreate(OCISvcCtx *svchp, OCIError *errhp, OCITypeCode tc, + OCIType *type, OCIDuration dur, OCIAnyData **sdata); + +sword OCIAnyDataDestroy(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata); + +sword OCIAnyDataAttrSet(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *attr_val, + ub4 length, boolean is_any); + +sword OCIAnyDataCollAddElem(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata, OCITypeCode tc, OCIType *type, void *ind, + void *attr_val, ub4 length, boolean is_any, boolean last_elem); + +sword OCIAnyDataEndCreate(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata); + +sword OCIAnyDataAccess(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *attr_val, + ub4 *length); + +sword OCIAnyDataGetCurrAttrNum(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata, ub4 *attrnum); + +sword OCIAnyDataAttrGet(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *attr_val, + ub4 *length, boolean is_any); + +sword OCIAnyDataCollGetElem(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *celem_val, + ub4 *length, boolean is_any); + + +/*------------------------ OCIAnyDataSet interfaces -------------------------*/ + +/* + NAME + OCIAnyDataSetBeginCreate - OCIAnyDataSet Begin Creation + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns OCI_ERROR. + Diagnostic information can be obtained by calling + OCIErrorGet(). + typecode - typecode corresponding to the OCIAnyDataSet. + type (IN) - type corresponding to the OCIAnyDataSet. If the typecode + corresponds to a built-in type (OCI_TYPECODE_NUMBER etc.) + , this parameter can be NULL. It should be non NULL for + user defined types (OCI_TYPECODE_OBJECT, + OCI_TYPECODE_REF, collection types etc.) + dur (IN) - duration for which OCIAnyDataSet is allocated. + data_set (OUT) - Initialized OCIAnyDataSet. + RETURNS - error code + NOTES + This call allocates an OCIAnyDataSet for the duration of dur and + initializes it with the type information. The OCIAnyDataSet can hold + multiple instances of the given type. For performance reasons, the + OCIAnyDataSet will end up pointing to the passed in OCIType parameter. + It is the responsibility of the caller to ensure that the OCIType is + longer lived (has allocation duration >= the duration of the OCIAnyData + if the OCIType is a transient one, allocation/pin duration >= duration of + the OCIAnyData if the OCIType is a persistent one). + +*/ +sword OCIAnyDataSetBeginCreate(OCISvcCtx *svchp, OCIError *errhp, + OCITypeCode typecode, const OCIType *type, OCIDuration dur, + OCIAnyDataSet ** data_set); + +/* + NAME + OCIAnyDataSetDestroy - OCIAnyDataSet Destroy + DESCRIPTION + This call frees the OCIAnyDataSet allocated using + OCIAnyDataSetBeginCreate(). + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI Error handle. + data_set (IN/OUT) - OCIAnyDataSet to be freed. +*/ +sword OCIAnyDataSetDestroy(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set); + + +/* + NAME + OCIAnyDataSetAddInstance - OCIAnyDataSet Add an instance + DESCRIPTION + This call adds a new skeleton instance to the OCIAnyDataSet and all the + attributes of the instance are set to NULL. It returns this skeleton + instance through the OCIAnyData parameter which can be constructed + subsequently by invoking the OCIAnyData API. + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI Error handle. + data_set (IN/OUT) - OCIAnyDataSet to which a new instance is added. + data (IN/OUT) - OCIAnyData corresponding to the newly added + instance. If (*data) is NULL, a new OCIAnyData will + be allocated for same duration as the OCIAnyDataSet. + If (*data) is not NULL, it will get reused. This + OCIAnyData can be subseqently constructed using the + OCIAnyDataConvert() call or it can be constructed + piece-wise using the OCIAnyDataAttrSet and + OCIAnyDataCollAddElem calls. + NOTES + No Destruction of the old value is done here. It is the responsibility of + the caller to destroy the old value pointed to by (*data) and set (*data) + to a null pointer before beginning to make a sequence of this call. No + deep copying (of OCIType information nor the data part.) is done in the + returned OCIAnyData. This OCIAnyData cannot be used beyond the allocation + duration of the OCIAnyDataSet (it is like a reference into the + OCIAnyDataSet). The returned OCIAnyData can be reused on subsequent calls + to this function, to sequentially add new data instances to the + OCIAnyDataSet. +*/ +sword OCIAnyDataSetAddInstance(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, OCIAnyData **data); + +/* + NAME + OCIAnyDataSetEndCreate - OCIAnyDataSet End Creation process. + DESCRIPTION + This call marks the end of OCIAnyDataSet creation. It should be called + after constructing all of its instance(s). + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained + by calling OCIErrorGet(). + data_set (IN/OUT) - OCIAnyDataSet that has been fully constructed. +*/ +sword OCIAnyDataSetEndCreate(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set); + +/* + NAME + OCIAnyDataSetGetType - OCIAnyDataSet Get Type of an OCIAnyDataSet + DESCRIPTION + Gets the Type corresponding to an OCIAnyDataSet. It returns the actual + pointer to the type maintained inside an OCIAnyDataSet. No copying is + done for performance reasons. The client is responsible for not using + this type once the OCIAnyDataSet is freed (or its duration ends). + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI Error handle. + data_set (IN) - Initialized OCIAnyDataSet. + tc (OUT) - The typecode of the type. + type (OUT) - The type corresponding to the OCIAnyDataSet. This + could be null if the OCIAnyData corresponds to a + built-in type. +*/ +sword OCIAnyDataSetGetType (OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, OCITypeCode *tc, OCIType **type); + +/* + NAME + OCIAnyDataSetGetCount - OCIAnyDataSet Get Count of instances. + DESCRIPTION + This call gets the number of instances in the OCIAnyDataSet. + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - OCI Service Context + errhp (IN/OUT) - OCI Error handle + data_set (IN) - Well formed OCIAnyDataSet. + count (OUT) - number of instances in OCIAnyDataSet +*/ +sword OCIAnyDataSetGetCount(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, ub4 *count); + +/* + NAME + OCIAnyDataSetGetInstance - OCIAnyDataSet Get next instance. + DESCRIPTION + Only sequential access to the instances in an OCIAnyDataSet is allowed. + This call returns the OCIAnyData corresponding to an instance at the + current position and updates the current position. Subsequently, the + OCIAnyData access routines may be used to access the instance. + RETURNS + error code. Returns OCI_NO_DATA if the current position is at the end of + the set, OCI_SUCCESS otherwise. + PARAMETERS + svchp (IN/OUT) - OCI Service Context + errhp (IN/OUT) - OCI Error handle + data_set (IN) - Well formed OCIAnyDataSet + data (IN/OUT) - OCIAnyData corresponding to the instance. If (*data) + is NULL, a new OCIAnyData will be allocated for same + duration as the OCIAnyDataSet. If (*data) is not NULL + , it will get reused. This OCIAnyData can be + subsequently accessed using the OCIAnyDataAccess() + call or piece-wise by using the OCIAnyDataAttrGet() + call. + NOTE + No Destruction of the old value is done here. It is the responsibility of + the caller to destroy the old value pointed to by (*data) and set (*data) + to a null pointer before beginning to make a sequence of this call. No deep + copying (of OCIType information nor the data part.) is done in the returned + OCIAnyData. This OCIAnyData cannot be used beyond the allocation duration + of the OCIAnyDataSet (it is like a reference into the OCIAnyDataSet). The + returned OCIAnyData can be reused on subsequent calls to this function to + sequentially access the OCIAnyDataSet. +*/ +sword OCIAnyDataSetGetInstance(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, OCIAnyData **data); + +/*--------------------- End of OCIAnyDataSet interfaces ---------------------*/ + +sword OCIFormatInit(void *hndl, OCIError *err); + +sword OCIFormatString(void *hndl, OCIError *err, OraText *buffer, + sbig_ora bufferLength, sbig_ora *returnLength, + const OraText *formatString, ...); + +sword OCIFormatTerm(void *hndl, OCIError *err); + +sword OCIFormatTUb1(void); +sword OCIFormatTUb2(void); +sword OCIFormatTUb4(void); +sword OCIFormatTUword(void); +sword OCIFormatTUbig_ora(void); +sword OCIFormatTSb1(void); +sword OCIFormatTSb2(void); +sword OCIFormatTSb4(void); +sword OCIFormatTSword(void); +sword OCIFormatTSbig_ora(void); +sword OCIFormatTEb1(void); +sword OCIFormatTEb2(void); +sword OCIFormatTEb4(void); +sword OCIFormatTEword(void); +sword OCIFormatTChar(void); +sword OCIFormatTText(void); +sword OCIFormatTDouble(void); +sword OCIFormatTDvoid(void); +sword OCIFormatTEnd(void); + +/*-------------------------- Extensions to XA interface ---------------------*/ +/* ------------------------- xaosvch ----------------------------------------*/ +/* + NAME + xaosvch - XA Oracle get SerViCe Handle + DESCRIPTION + Given a database name return the service handle that is used by the + XA library + NOTE + This macro has been provided for backward compatibilty with 8.0.2 +*/ +OCISvcCtx *xaosvch(OraText *dbname); + +/* ------------------------- xaoSvcCtx --------------------------------------*/ +/* + NAME + xaoSvcCtx - XA Oracle get SerViCe ConTeXt + DESCRIPTION + Given a database name return the service handle that is used by the + XA library + NOTE + This routine has been provided for APs to get access to the service + handle that XA library uses. Without this routine APs must use SQLLIB + routine sqlld2 to get access to the Logon data area registered by the + XA library +*/ +OCISvcCtx *xaoSvcCtx(OraText *dbname); + +/* ------------------------- xaoEnv -----------------------------------------*/ +/* + NAME + xaoEnv - XA Oracle get ENvironment Handle + DESCRIPTION + Given a database name return the environment handle that is used by the + XA library + NOTE + This routine has been provided for APs to get access to the environment + handle that XA library uses. Without this routine APs must use SQLLIB + routine sqlld2 to get access to the Logon data area registered by the + XA library +*/ +OCIEnv *xaoEnv(OraText *dbname); + +/* ------------------------- xaosterr ---------------------------------------*/ +/* + NAME + xaosterr - XA Oracle get xa STart ERRor code + DESCRIPTION + Given an oracle error code return the XA error code + */ +int xaosterr(OCISvcCtx *svch, sb4 error); +/*-------------------------- End Extensions ---------------------------------*/ +/*---------------------- Extensions to NLS cartridge service ----------------*/ +/* ----------------------- OCINlsGetInfo ------------------------------------*/ +/* + NAME + OCINlsGetInfo - Get NLS info from OCI environment handle + REMARKS + This function generates language information specified by item from OCI + environment handle envhp into an array pointed to by buf within size + limitation as buflen. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR on wrong item. + envhp(IN/OUT) + OCI environment handle. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and + this function returns a NULL pointer. Diagnostic information can be + obtained by calling OCIErrorGet(). + buf(OUT) + Pointer to the destination buffer. + buflen(IN) + The size of destination buffer. The maximum length for each information + is 32 bytes. + item(IN) + It specifies to get which item in OCI environment handle and can be one + of following values: + OCI_NLS_DAYNAME1 : Native name for Monday. + OCI_NLS_DAYNAME2 : Native name for Tuesday. + OCI_NLS_DAYNAME3 : Native name for Wednesday. + OCI_NLS_DAYNAME4 : Native name for Thursday. + OCI_NLS_DAYNAME5 : Native name for Friday. + OCI_NLS_DAYNAME6 : Native name for for Saturday. + OCI_NLS_DAYNAME7 : Native name for for Sunday. + OCI_NLS_ABDAYNAME1 : Native abbreviated name for Monday. + OCI_NLS_ABDAYNAME2 : Native abbreviated name for Tuesday. + OCI_NLS_ABDAYNAME3 : Native abbreviated name for Wednesday. + OCI_NLS_ABDAYNAME4 : Native abbreviated name for Thursday. + OCI_NLS_ABDAYNAME5 : Native abbreviated name for Friday. + OCI_NLS_ABDAYNAME6 : Native abbreviated name for for Saturday. + OCI_NLS_ABDAYNAME7 : Native abbreviated name for for Sunday. + OCI_NLS_MONTHNAME1 : Native name for January. + OCI_NLS_MONTHNAME2 : Native name for February. + OCI_NLS_MONTHNAME3 : Native name for March. + OCI_NLS_MONTHNAME4 : Native name for April. + OCI_NLS_MONTHNAME5 : Native name for May. + OCI_NLS_MONTHNAME6 : Native name for June. + OCI_NLS_MONTHNAME7 : Native name for July. + OCI_NLS_MONTHNAME8 : Native name for August. + OCI_NLS_MONTHNAME9 : Native name for September. + OCI_NLS_MONTHNAME10 : Native name for October. + OCI_NLS_MONTHNAME11 : Native name for November. + OCI_NLS_MONTHNAME12 : Native name for December. + OCI_NLS_ABMONTHNAME1 : Native abbreviated name for January. + OCI_NLS_ABMONTHNAME2 : Native abbreviated name for February. + OCI_NLS_ABMONTHNAME3 : Native abbreviated name for March. + OCI_NLS_ABMONTHNAME4 : Native abbreviated name for April. + OCI_NLS_ABMONTHNAME5 : Native abbreviated name for May. + OCI_NLS_ABMONTHNAME6 : Native abbreviated name for June. + OCI_NLS_ABMONTHNAME7 : Native abbreviated name for July. + OCI_NLS_ABMONTHNAME8 : Native abbreviated name for August. + OCI_NLS_ABMONTHNAME9 : Native abbreviated name for September. + OCI_NLS_ABMONTHNAME10 : Native abbreviated name for October. + OCI_NLS_ABMONTHNAME11 : Native abbreviated name for November. + OCI_NLS_ABMONTHNAME12 : Native abbreviated name for December. + OCI_NLS_YES : Native string for affirmative response. + OCI_NLS_NO : Native negative response. + OCI_NLS_AM : Native equivalent string of AM. + OCI_NLS_PM : Native equivalent string of PM. + OCI_NLS_AD : Native equivalent string of AD. + OCI_NLS_BC : Native equivalent string of BC. + OCI_NLS_DECIMAL : decimal character. + OCI_NLS_GROUP : group separator. + OCI_NLS_DEBIT : Native symbol of debit. + OCI_NLS_CREDIT : Native sumbol of credit. + OCI_NLS_DATEFORMAT : Oracle date format. + OCI_NLS_INT_CURRENCY: International currency symbol. + OCI_NLS_LOC_CURRENCY : Locale currency symbol. + OCI_NLS_LANGUAGE : Language name. + OCI_NLS_ABLANGUAGE : Abbreviation for language name. + OCI_NLS_TERRITORY : Territory name. + OCI_NLS_CHARACTER_SET : Character set name. + OCI_NLS_LINGUISTIC : Linguistic name. + OCI_NLS_CALENDAR : Calendar name. + OCI_NLS_DUAL_CURRENCY : Dual currency symbol. +*/ +sword OCINlsGetInfo(void *envhp, OCIError *errhp, OraText *buf, + size_t buflen, ub2 item); + +/* ----------------------- OCINlsNumericInfoGet -----------------------------*/ +/* + NAME + OCINlsNumericInfoGet - Get NLS numeric info from OCI environment handle + REMARKS + This function generates numeric language information specified by item + from OCI environment handle envhp into an output number variable. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR on wrong item. + envhp(IN/OUT) + OCI environment handle. If handle invalid, returns OCI_INVALID_HANDLE. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and + this function returns a NULL pointer. Diagnostic information can be + obtained by calling OCIErrorGet(). + val(OUT) + Pointer to the output number variable. On OCI_SUCCESS return, it will + contain the requested NLS numeric info. + item(IN) + It specifies to get which item in OCI environment handle and can be one + of following values: + OCI_NLS_CHARSET_MAXBYTESZ : Maximum character byte size for OCI + environment or session handle charset + OCI_NLS_CHARSET_FIXEDWIDTH: Character byte size for fixed-width charset; + 0 for variable-width charset +*/ +sword OCINlsNumericInfoGet(void *envhp, OCIError *errhp, sb4 *val, ub2 item); + +/* ----------------------- OCINlsCharSetNameToId ----------------------------*/ +/* + NAME + OCINlsCharSetNameToId - Get Oracle charset id given Oracle charset name + REMARKS + This function will get the Oracle character set id corresponding to + the given Oracle character set name. + RETURNS + Oracle character set id for the given Oracle character set name if + character set name and OCI handle are valid; otherwise returns 0. + envhp(IN/OUT) + OCI environment handle. + name(IN) + Pointer to a null-terminated Oracle character set name whose id + will be returned. +*/ +ub2 OCINlsCharSetNameToId(void *envhp, const oratext *name); + +/* ----------------------- OCINlsCharSetIdToName ----------------------------*/ +/* + NAME + OCINlsCharSetIdToName - Get Oracle charset name given Oracle charset id + REMARKS + This function will get the Oracle character set name corresponding to + the given Oracle character set id. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR + envhp(IN/OUT) + OCI environment handle. If handle invalid, returns OCI_INVALID_HANDLE. + buf(OUT) + Pointer to the destination buffer. On OCI_SUCCESS return, it will contain + the null-terminated string for character set name. + buflen(IN) + Size of destination buffer. Recommended size is OCI_NLS_MAXBUFSZ for + guarantee to store an Oracle character set name. If it's smaller than + the length of the character set name, the function will return OCI_ERROR. + id(IN) + Oracle character set id. +*/ +sword OCINlsCharSetIdToName(void *envhp, oratext *buf, size_t buflen, ub2 id); + +/* ----------------------- OCINlsNameMap ------------------------------------*/ +/* + NAME + OCINlsNameMap - Map NLS naming from Oracle to other standards and vice + versa + REMARKS + This function will map NLS naming from Oracle to other standards (such + as ISO, IANA) and vice versa. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR + envhp(IN/OUT) + OCI environment handle. If handle invalid, returns OCI_INVALID_HANDLE. + buf(OUT) + Pointer to the destination buffer. On OCI_SUCCESS return, it will + contain null-terminated string for requested mapped name. + buflen(IN) + The size of destination buffer. Recommended size is OCI_NLS_MAXBUFSZ + for guarantee to store an NLS name. If it is smaller than the length + of the name, the function will return OCI_ERROR. + srcbuf(IN) + Pointer to null-terminated NLS name. If it is not a valid name in its + define scope, the function will return OCI_ERROR. + flag(IN) + It specifies name mapping direction and can take the following values: + OCI_NLS_CS_IANA_TO_ORA : Map character set name from IANA to Oracle + OCI_NLS_CS_ORA_TO_IANA : Map character set name from Oracle to IANA + OCI_NLS_LANG_ISO_TO_ORA : Map language name from ISO to Oracle + OCI_NLS_LANG_ORA_TO_ISO : Map language name from Oracle to ISO + OCI_NLS_TERR_ISO_TO_ORA : Map territory name from ISO to Oracle + OCI_NLS_TERR_ORA_TO_ISO : Map territory name from Oracle to ISO + OCI_NLS_TERR_ISO3_TO_ORA : Map territory name from 3-letter ISO + abbreviation to Oracle + OCI_NLS_TERR_ORA_TO_ISO3 : Map territory name from Oracle to 3-letter + ISO abbreviation +*/ +sword OCINlsNameMap(void *envhp, oratext *buf, size_t buflen, + const oratext *srcbuf, ub4 flag); + +/* -------------------- OCIMultiByteToWideChar ------------------------------*/ +/* + NAME + OCIMultiByteToWideChar - Convert a null terminated multibyte string into + wchar + REMARKS + This routine converts an entire null-terminated string into the wchar + format. The wchar output buffer will be null-terminated. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Destination buffer for wchar. + src (IN) + Source string to be converted. + rsize (OUT) + Number of characters converted including null-terminator. + If it is a NULL pointer, no number return +*/ +sword OCIMultiByteToWideChar(void *envhp, OCIWchar *dst, const OraText *src, + size_t *rsize); + + +/* --------------------- OCIMultiByteInSizeToWideChar -----------------------*/ +/* + NAME + OCIMultiByteInSizeToWideChar - Convert a mulitbyte string in length into + wchar + REMARKS + This routine converts part of string into the wchar format. It will + convert as many complete characters as it can until it reaches output + buffer size or input buffer size or it reaches a null-terminator in + source string. The output buffer will be null-terminated if space permits. + If dstsz is zero, this function will only return number of characters not + including ending null terminator for converted string. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Pointer to a destination buffer for wchar. It can be NULL pointer when + dstsz is zero. + dstsz(IN) + Destination buffer size in character. If it is zero, this function just + returns number of characters will be need for the conversion. + src (IN) + Source string to be converted. + srcsz(IN) + Length of source string in byte. + rsize(OUT) + Number of characters written into destination buffer, or number of + characters for converted string is dstsz is zero. + If it is NULL pointer, nothing to return. +*/ +sword OCIMultiByteInSizeToWideChar(void *envhp, OCIWchar *dst, + size_t dstsz, const OraText *src, + size_t srcsz, size_t *rsize); + + +/* ---------------------- OCIWideCharToMultiByte ----------------------------*/ +/* + NAME + OCIWideCharToMultiByte - Convert a null terminated wchar string into + multibyte + REMARKS + This routine converts an entire null-terminated wide character string into + multi-byte string. The output buffer will be null-terminated. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Destination buffer for multi-byte string. + src (IN) + Source wchar string to be converted. + rsize (OUT) + Number of bytes written into the destination buffer. + If it is NULL pointer, nothing to return. +*/ +sword OCIWideCharToMultiByte(void *envhp, OraText *dst, const OCIWchar *src, + size_t *rsize); + + +/* ---------------------- OCIWideCharInSizeToMultiByte ----------------------*/ +/* + NAME + OCIWideCharInSizeToMultiByte - Convert a wchar string in length into + mulitbyte + REMARKS + This routine converts part of wchar string into the multi-byte format. + It will convert as many complete characters as it can until it reaches + output buffer size or input buffer size or it reaches a null-terminator + in source string. The output buffer will be null-terminated if space + permits. If dstsz is zero, the function just returns the size of byte not + including ending null-terminator need to store the converted string. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Destination buffer for multi-byte. It can be NULL pointer if dstsz is + zero. + dstsz(IN) + Destination buffer size in byte. If it is zero, it just returns the size + of bytes need for converted string. + src (IN) + Source wchar string to be converted. + srcsz(IN) + Length of source string in character. + rsize(OUT) + Number of bytes written into destination buffer, or number of bytes need + to store the converted string if dstsz is zero. + If it is NULL pointer, nothing to return. +*/ +sword OCIWideCharInSizeToMultiByte(void *envhp, OraText *dst, + size_t dstsz, const OCIWchar *src, + size_t srcsz, size_t *rsize); + + + +/* ----------------------- OCIWideCharIsAlnum -------------------------------*/ +/* + NAME + OCIWideCharIsAlnum - test whether wc is a letter or decimal digit + REMARKS + It tests whether wc is a letter or decimal digit. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsAlnum(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsAlpha -------------------------------*/ +/* + NAME + OCIWideCharIsAlpha - test whether wc is an alphabetic letter + REMARKS + It tests whether wc is an alphabetic letter + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsAlpha(void *envhp, OCIWchar wc); + + +/* --------------------- OCIWideCharIsCntrl ---------------------------------*/ +/* + NAME + OCIWideCharIsCntrl - test whether wc is a control character + REMARKS + It tests whether wc is a control character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsCntrl(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsDigit -------------------------------*/ +/* + NAME + OCIWideCharIsDigit - test whether wc is a decimal digit character + REMARKS + It tests whether wc is a decimal digit character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsDigit(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsGraph -------------------------------*/ +/* + NAME + OCIWideCharIsGraph - test whether wc is a graph character + REMARKS + It tests whether wc is a graph character. A graph character is character + with a visible representation and normally includes alphabetic letter, + decimal digit, and punctuation. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsGraph(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsLower -------------------------------*/ +/* + NAME + OCIWideCharIsLower - test whether wc is a lowercase letter + REMARKS + It tests whether wc is a lowercase letter. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsLower(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsPrint -------------------------------*/ +/* + NAME + OCIWideCharIsPrint - test whether wc is a printable character + REMARKS + It tests whether wc is a printable character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsPrint(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsPunct -------------------------------*/ +/* + NAME + OCIWideCharIsPunct - test whether wc is a punctuation character + REMARKS + It tests whether wc is a punctuation character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsPunct(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsSpace -------------------------------*/ +/* + NAME + OCIWideCharIsSpace - test whether wc is a space character + REMARKS + It tests whether wc is a space character. A space character only causes + white space in displayed text(for example, space, tab, carriage return, + newline, vertical tab or form feed). + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsSpace(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsUpper -------------------------------*/ +/* + NAME + OCIWideCharIsUpper - test whether wc is a uppercase letter + REMARKS + It tests whether wc is a uppercase letter. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsUpper(void *envhp, OCIWchar wc); + + +/*----------------------- OCIWideCharIsXdigit -------------------------------*/ +/* + NAME + OCIWideCharIsXdigit - test whether wc is a hexadecimal digit + REMARKS + It tests whether wc is a hexadecimal digit ( 0-9, A-F, a-f ). + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsXdigit(void *envhp, OCIWchar wc); + + +/* --------------------- OCIWideCharIsSingleByte ----------------------------*/ +/* + NAME + OCIWideCharIsSingleByte - test whether wc is a single-byte character + REMARKS + It tests whether wc is a single-byte character when converted into + multi-byte. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsSingleByte(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharToLower -------------------------------*/ +/* + NAME + OCIWideCharToLower - Convert a wchar into the lowercase + REMARKS + If there is a lower-case character mapping for wc in the specified locale, + it will return the lower-case in wchar, else return wc itself. + RETURNS + A wchar + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for lowercase mapping. +*/ +OCIWchar OCIWideCharToLower(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharToUpper -------------------------------*/ +/* + NAME + OCIWideCharToUpper - Convert a wchar into the uppercase + REMARKS + If there is a upper-case character mapping for wc in the specified locale, + it will return the upper-case in wchar, else return wc itself. + RETURNS + A wchar + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for uppercase mapping. +*/ +OCIWchar OCIWideCharToUpper(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharStrcmp --------------------------------*/ +/* + NAME + OCIWideCharStrcmp - compare two null terminated wchar string + REMARKS + It compares two wchar string in binary ( based on wchar encoding value ), + linguistic, or case-insensitive. + RETURNS + 0, if wstr1 == wstr2. + Positive, if wstr1 > wstr2. + Negative, if wstr1 < wstr2. + envhp(IN/OUT) + OCI environment handle to determine the character set. + wstr1(IN) + Pointer to a null-terminated wchar string. + wstr2(IN) + Pointer to a null-terminated wchar string. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY : for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC : for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIWideCharStrcmp(void *envhp, const OCIWchar *wstr1, + const OCIWchar *wstr2, int flag); + + +/* ----------------------- OCIWideCharStrncmp -------------------------------*/ +/* + NAME + OCIWideCharStrncmp - compare twe wchar string in length + REMARKS + This function is similar to OCIWideCharStrcmp(), except that at most len1 + characters from wstr1 and len2 characters from wstr1 are compared. The + null-terminator will be taken into the comparison. + RETURNS + 0, if wstr1 = wstr2 + Positive, if wstr1 > wstr2 + Negative, if wstr1 < wstr2 + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr1(IN) + Pointer to the first wchar string + len1(IN) + The length for the first string for comparison + wstr2(IN) + Pointer to the second wchar string + len2(IN) + The length for the second string for comparison. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY : for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC : for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIWideCharStrncmp(void *envhp, const OCIWchar *wstr1, size_t len1, + const OCIWchar *wstr2, size_t len2, int flag); + + +/* ----------------------- OCIWideCharStrcat --------------------------------*/ +/* + NAME + OCIWideCharStrcat - concatenate two wchar strings + REMARKS + This function appends a copy of the wchar string pointed to by wsrcstr, + including the null-terminator to the end of wchar string pointed to by + wdststr. It returns the number of character in the result string not + including the ending null-terminator. + RETURNS + number of characters in the result string not including the ending + null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(IN/OUT) + Pointer to the destination wchar string for appending. + wsrcstr(IN) + Pointer to the source wchar string to append. +*/ +size_t OCIWideCharStrcat(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr); + + +/* ----------------------- OCIWideCharStrchr --------------------------------*/ +/* + NAME + OCIWideCharStrchr - Search the first occurrence of wchar in a wchar string + REMARKS + This function searchs for the first occurrence of wc in the wchar string + pointed to by wstr. It returns a pointer to the whcar if successful, or + a null pointer. + RETURNS + wchar pointer if successful, otherwise a null pointer. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr(IN) + Pointer to the wchar string to search + wc(IN) + Wchar to search for. +*/ +OCIWchar *OCIWideCharStrchr(void *envhp, const OCIWchar *wstr, + OCIWchar wc); + + +/* ----------------------- OCIWideCharStrcpy --------------------------------*/ +/* + NAME + OCIWideCharStrcpy - copy a wchar string + REMARKS + This function copies the wchar string pointed to by wsrcstr, including the + null-terminator, into the array pointed to by wdststr. It returns the + number of character copied not including the ending null-terminator. + RETURNS + number of characters copied not including the ending null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(OUT) + Pointer to the destination wchar buffer. + wsrcstr(IN) + Pointer to the source wchar string. +*/ +size_t OCIWideCharStrcpy(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr); + + +/* ----------------------- OCIWideCharStrlen --------------------------------*/ +/* + NAME + OCIWideCharStrlen - Return number of character in a wchar string + REMARKS + This function computes the number of characters in the wchar string + pointed to by wstr, not including the null-terminator, and returns + this number. + RETURNS + number of characters not including ending null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr(IN) + Pointer to the source wchar string. +*/ +size_t OCIWideCharStrlen(void *envhp, const OCIWchar *wstr); + + +/* ----------------------- OCIWideCharStrncat -------------------------------*/ +/* + NAME + OCIWideCharStrncat - Concatenate wchar string in length + REMARKS + This function is similar to OCIWideCharStrcat(), except that at most n + characters from wsrcstr are appended to wdststr. Note that the + null-terminator in wsrcstr will stop appending. wdststr will be + null-terminated.. + RETURNS + Number of characters in the result string not including the ending + null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(IN/OUT) + Pointer to the destination wchar string for appending. + wsrcstr(IN) + Pointer to the source wchar string to append. + n(IN) + Number of characters from wsrcstr to append. +*/ +size_t OCIWideCharStrncat(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr, size_t n); + + +/* ----------------------- OCIWideCharStrncpy -------------------------------*/ +/* + NAME + OCIWideCharStrncpy - Copy wchar string in length + REMARKS + This function is similar to OCIWideCharStrcpy(), except that at most n + characters are copied from the array pointed to by wsrcstr to the array + pointed to by wdststr. Note that the null-terminator in wdststr will + stop coping and result string will be null-terminated. + RETURNS + number of characters copied not including the ending null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(OUT) + Pointer to the destination wchar buffer. + wsrcstr(IN) + Pointer to the source wchar string. + n(IN) + Number of characters from wsrcstr to copy. +*/ +size_t OCIWideCharStrncpy(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr, size_t n); + + +/* ----------------------- OCIWideCharStrrchr -------------------------------*/ +/* + NAME + OCIWideCharStrrchr - search the last occurrence of a wchar in wchar string + REMARKS + This function searchs for the last occurrence of wc in the wchar string + pointed to by wstr. It returns a pointer to the whcar if successful, or + a null pointer. + RETURNS + wchar pointer if successful, otherwise a null pointer. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr(IN) + Pointer to the wchar string to search + wc(IN) + Wchar to search for. +*/ +OCIWchar *OCIWideCharStrrchr(void *envhp, const OCIWchar *wstr, + OCIWchar wc); + + +/* --------------------- OCIWideCharStrCaseConversion -----------------------*/ +/* + NAME + OCIWideCharStrCaseConversion - convert a wchar string into lowercase or + uppercase + REMARKS + This function convert the wide char string pointed to by wsrcstr into the + uppercase or lowercase specified by flag and copies the result into the + array pointed to by wdststr. The result string will be null-terminated. + RETURNS + number of characters for result string not including null-terminator. + envhp(IN/OUT) + OCI environment handle. + wdststr(OUT) + Pointer to destination array. + wsrcstr(IN) + Pointer to source string. + flag(IN) + Specify the case to convert: + OCI_NLS_UPPERCASE : convert to uppercase. + OCI_NLS_LOWERCASE: convert to lowercase. + This flag can be ORed with OCI_NLS_LINGUISTIC to specify that the + linguistic setting in the locale will be used for case conversion. +*/ +size_t OCIWideCharStrCaseConversion(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr, ub4 flag); + + +/*---------------------- OCIWideCharDisplayLength ---------------------------*/ +/* + NAME + OCIWideCharDisplayLength - Calculate the display length for a wchar + REMARKS + This function determines the number of column positions required for wc + in display. It returns number of column positions, or 0 if wc is + null-terminator. + RETURNS + Number of display positions. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar character. +*/ +size_t OCIWideCharDisplayLength(void *envhp, OCIWchar wc ); + + +/*---------------------- OCIWideCharMultiByteLength -------------------------*/ +/* + NAME + OCIWideCharMultiByteLength - Determine byte size in multi-byte encoding + REMARKS + This function determines the number of byte required for wc in multi-byte + encoding. It returns number of bytes in multi-byte for wc. + RETURNS + Number of bytes. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar character. +*/ +size_t OCIWideCharMultiByteLength(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIMultiByteStrcmp -------------------------------*/ +/* + NAME + OCIMultiByteStrcmp - Compare two multi-byte strings + REMARKS + It compares two multi-byte strings in binary ( based on encoding value ), + linguistic, or case-insensitive. + RETURNS + 0, if str1 == str2. + Positive, if str1 > str2. + Negative, if str1 < str2. + envhp(IN/OUT) + OCI environment handle to determine the character set. + str1(IN) + Pointer to a null-terminated string. + str2(IN) + Pointer to a null-terminated string. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY: for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC: for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIMultiByteStrcmp(void *envhp, const OraText *str1, + const OraText *str2, int flag); + + +/*----------------------- OCIMultiByteStrncmp -------------------------------*/ +/* + NAME + OCIMultiByteStrncmp - compare two strings in length + REMARKS + This function is similar to OCIMultiBytestrcmp(), except that at most + len1 bytes from str1 and len2 bytes from str2 are compared. The + null-terminator will be taken into the comparison. + RETURNS + 0, if str1 = str2 + Positive, if str1 > str2 + Negative, if str1 < str2 + envhp(IN/OUT) + OCI environment handle to determine the character set. + str1(IN) + Pointer to the first string + len1(IN) + The length for the first string for comparison + str2(IN) + Pointer to the second string + len2(IN) + The length for the second string for comparison. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY: for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC: for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIMultiByteStrncmp(void *envhp, const OraText *str1, size_t len1, + OraText *str2, size_t len2, int flag); + + +/*----------------------- OCIMultiByteStrcat --------------------------------*/ +/* + NAME + OCIMultiByteStrcat - concatenate multibyte strings + REMARKS + This function appends a copy of the multi-byte string pointed to by + srcstr, including the null-terminator to the end of string pointed to by + dststr. It returns the number of bytes in the result string not including + the ending null-terminator. + RETURNS + number of bytes in the result string not including the ending + null-terminator. + envhp(IN/OUT) + Pointer to OCI environment handle + dststr(IN/OUT) + Pointer to the destination multi-byte string for appending. + srcstr(IN) + Pointer to the source string to append. +*/ +size_t OCIMultiByteStrcat(void *envhp, OraText *dststr, + const OraText *srcstr); + + +/*------------------------- OCIMultiByteStrcpy ------------------------------*/ +/* + NAME + OCIMultiByteStrcpy - copy multibyte string + REMARKS + This function copies the multi-byte string pointed to by srcstr, + including the null-terminator, into the array pointed to by dststr. It + returns the number of bytes copied not including the ending + null-terminator. + RETURNS + number of bytes copied not including the ending null-terminator. + envhp(IN/OUT) + Pointer to the OCI environment handle. + srcstr(OUT) + Pointer to the destination buffer. + dststr(IN) + Pointer to the source multi-byte string. +*/ +size_t OCIMultiByteStrcpy(void *envhp, OraText *dststr, + const OraText *srcstr); + + +/*----------------------- OCIMultiByteStrlen --------------------------------*/ +/* + NAME + OCIMultiByteStrlen - Calculate multibyte string length + REMARKS + This function computes the number of bytes in the multi-byte string + pointed to by str, not including the null-terminator, and returns this + number. + RETURNS + number of bytes not including ending null-terminator. + str(IN) + Pointer to the source multi-byte string. +*/ +size_t OCIMultiByteStrlen(void *envhp, const OraText *str); + + +/*----------------------- OCIMultiByteStrncat -------------------------------*/ +/* + NAME + OCIMultiByteStrncat - concatenate string in length + REMARKS + This function is similar to OCIMultiBytestrcat(), except that at most n + bytes from srcstr are appended to dststr. Note that the null-terminator in + srcstr will stop appending and the function will append as many character + as possible within n bytes. dststr will be null-terminated. + RETURNS + Number of bytes in the result string not including the ending + null-terminator. + envhp(IN/OUT) + Pointer to OCI environment handle. + srcstr(IN/OUT) + Pointer to the destination multi-byte string for appending. + dststr(IN) + Pointer to the source multi-byte string to append. + n(IN) + Number of bytes from srcstr to append. +*/ +size_t OCIMultiByteStrncat(void *envhp, OraText *dststr, + const OraText *srcstr, size_t n); + + +/*----------------------- OCIMultiByteStrncpy -------------------------------*/ +/* + NAME + OCIMultiByteStrncpy - copy multibyte string in length + REMARKS + This function is similar to OCIMultiBytestrcpy(), except that at most n + bytes are copied from the array pointed to by srcstr to the array pointed + to by dststr. Note that the null-terminator in srcstr will stop coping and + the function will copy as many character as possible within n bytes. The + result string will be null-terminated. + RETURNS + number of bytes copied not including the ending null-terminator. + envhp(IN/OUT) + Pointer to a OCI environment handle. + dststr(IN) + Pointer to the source multi-byte string. + srcstr(OUT) + Pointer to the destination buffer. + n(IN) + Number of bytes from srcstr to copy. +*/ +size_t OCIMultiByteStrncpy(void *envhp, OraText *dststr, + const OraText *srcstr, size_t n); + + +/*----------------------- OCIMultiByteStrnDisplayLength ---------------------*/ +/* + NAME + OCIMultiByteStrnDisplayLength - calculate the display length for a + multibyt string + REMARKS + This function returns the number of display positions occupied by the + complete characters within the range of n bytes. + RETURNS + number of display positions. + envhp(IN/OUT) + OCI environment handle. + str(IN) + Pointer to a multi-byte string. + n(IN) + Number of bytes to examine. +*/ +size_t OCIMultiByteStrnDisplayLength(void *envhp, const OraText *str1, + size_t n); + + +/*---------------------- OCIMultiByteStrCaseConversion ---------------------*/ +/* + NAME + OCIMultiByteStrCaseConversion + REMARKS + This function convert the multi-byte string pointed to by srcstr into the + uppercase or lowercase specified by flag and copies the result into the + array pointed to by dststr. The result string will be null-terminated. + RETURNS + number of bytes for result string not including null-terminator. + envhp(IN/OUT) + OCI environment handle. + dststr(OUT) + Pointer to destination array. + srcstr(IN) + Pointer to source string. + flag(IN) + Specify the case to convert: + OCI_NLS_UPPERCASE: convert to uppercase. + OCI_NLS_LOWERCASE: convert to lowercase. + This flag can be ORed with OCI_NLS_LINGUISTIC to specify that the + linguistic setting in the locale will be used for case conversion. +*/ +size_t OCIMultiByteStrCaseConversion(void *envhp, OraText *dststr, + const OraText *srcstr, ub4 flag); + + +/*------------------------- OCICharSetToUnicode -----------------------------*/ +/* + NAME + OCICharSetToUnicode - convert multibyte string into Unicode as UCS2 + REMARKS + This function converts a multi-byte string pointed to by src to Unicode + into the array pointed to by dst. The conversion will stop when it reach + to the source limitation or destination limitation. + The function will return number of characters converted into Unicode. + If dstlen is zero, it will just return the number of characters for the + result without real conversion. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + Pointer to an OCI environment handle + dst(OUT) + Pointer to a destination buffer + dstlen(IN) + Size of destination buffer in character + src(IN) + Pointer to multi-byte source string. + srclen(IN) + Size of source string in bytes. + rsize(OUT) + Number of characters converted. + If it is a NULL pointer, nothing to return. +*/ +sword OCICharSetToUnicode(void *envhp, ub2 *dst, size_t dstlen, + const OraText *src, size_t srclen, size_t *rsize); + + +/*------------------------- OCIUnicodeToCharSet -----------------------------*/ +/* + NAME + OCIUnicodeToCharSet - convert Unicode into multibyte + REMARKS + This function converts a Unicode string pointed to by src to multi-byte + into the array pointed to by dst. The conversion will stop when it reach + to the source limitation or destination limitation. The function will + return number of bytes converted into multi-byte. If dstlen is zero, it + will just return the number of bytes for the result without real + conversion. If a Unicode character is not convertible for the character + set specified in OCI environment handle, a replacement character will be + used for it. In this case, OCICharSetConversionIsReplacementUsed() will + return ture. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + Pointer to an OCI environment handle. + dst(OUT) + Pointer to a destination buffer. + dstlen(IN) + Size of destination buffer in byte. + src(IN) + Pointer to a Unicode string. + srclen(IN) + Size of source string in characters. + rsize(OUT) + Number of bytes converted. + If it is a NULL pointer, nothing to return. +*/ +sword OCIUnicodeToCharSet(void *envhp, OraText *dst, size_t dstlen, + const ub2 *src, size_t srclen, size_t *rsize); + +/*----------------------- OCINlsCharSetConvert ------------------------------*/ +/* + NAME + OCINlsCharSetConvert - convert between any two character set. + REMARKS + This function converts a string pointed to by src in the character set + specified with srcid to the array pointed to by dst in the character set + specified with dstid. The conversion will stop when it reaches the source + limitation or destination limitation. The function will return the number + of bytes converted into the destination buffer. Even though either source + or destination character set id is OCI_UTF16ID, given and return data + length will be represented with the byte length as this function is + intended for generic purpose. Note the conversion will not stop at null + data. + To get character set id from name, OCINlsCharSetNameToId can be used. + To check if derived data in the destination buffer contains any + replacement character resulting from conversion failure, + OCICharSetConversionIsReplacementUsed can be used to get the status. + Data alignment should be guaranteed by a caller. For example, UTF-16 data + should be aligned to ub2 type. + + RETURNS + OCI_SUCCESS or OCI_ERROR. + errhp(IN/OUT) + OCI error handle. If there is an error, it is recorded in errhp and this + function returns a NULL pointer. Diagnostic information can be obtained + by calling OCIErrorGet(). + dstid(IN) + Character set id for the destination buffer. + dstp(OUT) + Pointer to the destination buffer. + dstlen(IN) + The maximum byte size of destination buffer. + srcid(IN) + Character set id for the source buffer. + srcp(IN) + Pointer to the source buffer. + srclen(IN) + The length byte size of source buffer. + rsize(OUT) + The number of characters converted. If it is a NULL pointer, nothing to + return. +*/ +sword OCINlsCharSetConvert(void *envhp, OCIError *errhp, + ub2 dstid, void *dstp, size_t dstlen, + ub2 srcid, const void *srcp, size_t srclen, + size_t *rsize); + + +/* ------------------- OCICharsetConversionIsReplacementUsed ----------------*/ +/* + NAME + OCICharsetConversionIsReplacementUsed - chech if replacement is used in + conversion + REMARKS + This function indicates whether or not the replacement character was used + for nonconvertible characters in character set conversion in last invoke + of OCICharsetUcs2ToMb(). + RETURNS + TRUE is the replacement character was used in last OCICharsetUcs2ToMb() + invoking, else FALSE. + envhp(IN/OUT) + OCI environment handle. This should be the first handle passed to + OCICharsetUcs2ToMb(). +*/ +boolean OCICharSetConversionIsReplacementUsed(void *envhp); + +/*------------------- OCINlsEnvironmentVariableGet -----------------*/ +/* + NAME + OCINlsEnvironmentVariableGet - get a value of NLS environment variable. + + DESCRIPTION + This function retrieves a value of NLS environment variable to the buffer + pointed to by val. Data type is determined by the parameter specified by + item. Either numeric data or string data can be retrieved. + + RETURNS + OCI_SUCCESS or OCI_ERROR. + + PARAMETERS + valp(OUT) - + Pointer to the buffer. + size(IN) - + Size of the buffer. This argument is only applicable to string data type, + but not to numerical data, in such case, it is ignored. + item(IN) - + NLS item value, which can be one of following values: + OCI_NLS_CHARSET_ID - NLS_LANG character set id in ub2 data type. + OCI_NLS_NCHARSET_ID - NLS_NCHAR character set id in ub2 data type. + charset(IN) - + Character set id for retrieved string data. If it is 0, NLS_LANG will be + used. OCI_UTF16ID is a valid id. In case of numeric data, this argument + is ignored. + rsize(OUT) - + Size of return value. + + NOTE + This functions is mainly used for retrieving character set id from either + NLS_LANG or NLS_NCHAR environment variables. If NLS_LANG is not set, + the default character set id is returned. + For future extension, the buffer is capable for storing other data types. +*/ +sword OCINlsEnvironmentVariableGet(void *valp, size_t size, ub2 item, + ub2 charset, size_t *rsize); + + +/*------------------------- OCIMessageOpen ----------------------------------*/ +/* + NAME + OCIMessageOpen - open a locale message file + REMARKS + This function opens a message handle for facility of product in a language + pointed to by envhp. It first try to open the message file corresponding + to envhp for the facility. If it successes, it will use that file to + initialize a message handle, else it will use the default message file + which is for American language for the facility. The function return a + pointer pointed to a message handle into msghp parameter. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + A pointer to OCI environment handle for message language. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and this + function returns a NULL pointer. Diagnostic information can be obtained by + calling OCIErrorGet(). + msghp(OUT) + a message handle for return + product(IN) + A pointer to a product name. Product name is used to locate the directory + for message in a system dependent way. For example, in Solaris, the + directory of message files for the product `rdbms' is + `${ORACLE_HOME}/rdbms'. + facility(IN) + A pointer to a facility name in the product. It is used to construct a + message file name. A message file name follows the conversion with + facility as prefix. For example, the message file name for facility + `img' in American language will be `imgus.msb' where `us' is the + abbreviation of American language and `msb' as message binary file + extension. + dur(IN) + Duration for memory allocation for the return message handle. It can be + the following values: + OCI_DURATION_CALL + OCI_DURATION_STATEMENT + OCI_DURATION_SESSION + OCI_DURATION_TRANSACTION + For the detail description, please refer to Memory Related Service + Interfaces section. +*/ +sword OCIMessageOpen(void *envhp, OCIError *errhp, OCIMsg **msghp, + const OraText *product, const OraText *facility, + OCIDuration dur); + + +/*------------------------- OCIMessageGet -----------------------------------*/ +/* + NAME + OCIMessageGet - get a locale message from a message handle + REMARKS + This function will get message with message number identified by msgno and + if buflen is not zero, the function will copy the message into the buffer + pointed to by msgbuf. If buflen is zero, the message will be copied into + a message buffer inside the message handle pointed to by msgh. For both + cases. it will return the pointer to the null-terminated message string. + If it cannot get the message required, it will return a NULL pointer. + RETURNS + A pointer to a null-terminated message string on success, otherwise a NULL + pointer. + msgh(IN/OUT) + Pointer to a message handle which was previously opened by + OCIMessageOpen(). + msgno(IN) + The message number for getting message. + msgbuf(OUT) + Pointer to a destination buffer to the message retrieved. If buflen is + zero, it can be NULL pointer. + buflen(IN) + The size of the above destination buffer. +*/ +OraText *OCIMessageGet(OCIMsg *msgh, ub4 msgno, OraText *msgbuf, + size_t buflen); + +/*------------------------- OCIMessageClose ---------------------------------*/ +/* + NAME + OCIMessageClose - close a message handle + REMARKS + This function closes a message handle pointed to by msgh and frees any + memory associated with this handle. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + A pointer to OCI environment handle for message language. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and this + function returns a NULL pointer. Diagnostic information can be obtained by + calling OCIErrorGet(). + msghp(IN/OUT) + A pointer to a message handle which was previously opened by + OCIMessageOpen(). +*/ +sword OCIMessageClose(void *envhp, OCIError *errhp, OCIMsg *msghp); + +/*--------------- End of Extensions to NLS cartridge service ----------------*/ + + +/*----------------- Extensions to OCI Thread interface ---------------------*/ +/***************************************************************************** + DESCRIPTION +****************************************************************************** +1 Threads Interface + +The OCIThread package provides a number of commonly used threading +primitives for use by Oracle customers. It offers a portable interface to +threading capabilities native to various platforms. It does not implement +threading on platforms which do not have native threading capability. + +OCIThread does not provide a portable implementation of multithreaded +facilities. It only serves as a set of portable covers for native +multithreaded facilities. Therefore, platforms that do not have native +support for multi-threading will only be able to support a limited +implementation of OCIThread. As a result, products that rely on all of +OCIThread's functionality will not port to all platforms. Products that must +port to all platforms must use only a subset of OCIThread's functionality. +This issue is discussed further in later sections of this document. + +The OCIThread API is split into four main parts. Each part is described +briefly here. The following subsections describe each in greater detail. + + 1. Initialization and Termination Calls + + These calls deal with the initialization and termination of OCIThread. + Initialization of OCIThread initializes the OCIThread context which is + a member of the OCI environment or session handle. This context is + required for other OCIThread calls. + + 2. Passive Threading Primitives + + The passive threading primitives include primitives to manipulate mutual + exclusion (mutex) locks, thread ID's, and thread-specific data keys. + + The reason that these primitives are described as 'passive' is that while + their specifications allow for the existence of multiple threads, they do + not require it. This means that it is possible for these primitives to + be implemented according to specification in both single-threaded and + multi-threaded environments. + + As a result, OCIThread clients that use only these primitives will not + require the existence of multiple threads in order to work correctly, + i.e., they will be able to work in single-threaded environments without + branching code. + + 3. Active Threading Primitives + + Active threading primitives include primitives dealing with the creation, + termination, and other manipulation of threads. + + The reason that these primitives are described as 'active' is that they + can only be used in true multi-threaded environments. Their + specifications explicitly require that it be possible to have multiple + threads. If you need to determine at runtime whether or not you are in a + multi-threaded environment, call OCIThreadIsMulti() before calling an + OCIThread active primitive. + + +1.1 Initialization & Termination +================================== + +The types and functions described in this section are associated with the +initialization and termination of the OCIThread package. OCIThread must +be properly initialized before any of its functionality can be used. +OCIThread's process initialization function, 'OCIThreadProcessInit()', +must be called with care; see below. + +The observed behavior of the initialization and termination functions is the +same regardless of whether OCIThread is in single-threaded or multi-threaded +environment. It is OK to call the initialization functions from both generic +and operating system specific (OSD) code. + +1.1.1 Types + + OCIThreadContext - OCIThread Context + ------------------------------------- + + Most calls to OCIThread functions take the OCI environment or session + handle as a parameter. The OCIThread context is part of the OCI + environment or session handle and it must be initialized by calling + 'OCIThreadInit()'. Termination of the OCIThread context occurs by calling + 'OCIThreadTerm()'. + + The OCIThread context is a private data structure. Clients must NEVER + attempt to examine the contents of the context. + +1.1.2 OCIThreadProcessInit + + OCIThreadProcessInit - OCIThread Process INITialization + -------------------------------------------------------- + + Description + + This function should be called to perform OCIThread process + initialization. + + Prototype + + void OCIThreadProcessInit(); + + Returns + + Nothing. + + Notes + + Whether or not this function needs to be called depends on how OCI + Thread is going to be used. + + * In a single-threaded application, calling this function is optional. + If it is called at all, the first call to it must occur before calls + to any other OCIThread functions. Subsequent calls can be made + without restriction; they will not have any effect. + + * In a multi-threaded application, this function MUST be called. The + first call to it MUST occur 'strictly before' any other OCIThread + calls; i.e., no other calls to OCIThread functions (including other + calls to this one) can be concurrent with the first call. + Subsequent calls to this function can be made without restriction; + they will not have any effect. + + +1.1.3 OCIThreadInit + + OCIThreadInit - OCIThread INITialize + ------------------------------------- + + Description + + This initializes OCIThread context. + + Prototype + + sword OCIThreadInit(void *hndl, OCIError *err); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal for OCIThread clients to try an examine the memory + pointed to by the returned pointer. + + It is safe to make concurrent calls to 'OCIThreadInit()'. Unlike + 'OCIThreadProcessInit()', there is no need to have a first call + that occurs before all the others. + + The first time 'OCIThreadInit()' is called, it initilaizes the OCI + Thread context. It also saves a pointer to the context in some system + dependent manner. Subsequent calls to 'OCIThreadInit()' will return + the same context. + + Each call to 'OCIThreadInit()' must eventually be matched by a call to + 'OCIThreadTerm()'. + + OCIThreadTerm - OCIThread TERMinate + ------------------------------------ + + Description + + This should be called to release the OCIThread context. It should be + called exactly once for each call made to 'OCIThreadInit()'. + + Prototype + + sword OCIThreadTerm(void *hndl, OCIError *err); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is safe to make concurrent calls to 'OCIThreadTerm()'. + + 'OCIThreadTerm()' will not do anything until it has been called as + many times as 'OCIThreadInit()' has been called. When that happens, + it terminates the OCIThread layer and frees the memory allocated for + the context. Once this happens, the context should not be re-used. + It will be necessary to obtain a new one by calling 'OCIThreadInit()'. + + + OCIThreadIsMulti - OCIThread Is Multi-Threaded? + ------------------------------------------------ + + Description + + This tells the caller whether the application is running in a + multi-threaded environment or a single-threaded environment. + + Prototype + boolean OCIThreadIsMulti(void); + + Returns + + TRUE if the environment is multi-threaded; + FALSE if the environment is single-threaded. + + +1.2 Passive Threading Primitives +================================== + +1.2.1 Types + +The passive threading primitives deal with the manipulation of mutex, +thread ID's, and thread-specific data. Since the specifications of these +primitives do not require the existence of multiple threads, they can be +used both on multithreaded and single-threaded platforms. + +1.2.1.1 OCIThreadMutex - OCIThread Mutual Exclusion Lock +----------------------------------------------------------- + + The type 'OCIThreadMutex' is used to represent a mutual exclusion lock + (mutex). A mutex is typically used for one of two purposes: (i) to + ensure that only one thread accesses a given set of data at a time, or + (ii) to ensure that only one thread executes a given critical section of + code at a time. + + Mutexes pointer can be declared as parts of client structures or as + stand-alone variables. Before they can be used, they must be initialized + using 'OCIThreadMutexInit()'. Once they are no longer needed, they must be + destroyed using 'OCIThreadMutexDestroy()'. A mutex pointer must NOT be + used after it is destroyed. + + A thread can acquire a mutex by using either 'OCIThreadMutexAcquire()' or + 'OCIThreadMutexTry()'. They both ensure that only one thread at a time is + allowed to hold a given mutex. A thread that holds a mutex can release it + by calling 'OCIThreadMutexRelease()'. + + +1.2.1.2 OCIThreadKey - OCIThread Key for Thread-Specific Data +---------------------------------------------------------------- + + A key can be thought of as a process-wide variable that has a + thread-specific value. What this means is that all the threads in a + process can use any given key. However, each thread can examine or modify + that key independently of the other threads. The value that a thread sees + when it examines the key will always be the same as the value that it last + set for the key. It will not see any values set for the key by the other + threads. + + The type of the value held by a key is a 'void *' generic pointer. + + Keys can be created using 'OCIThreadKeyInit()'. When a key is created, its + value is initialized to 'NULL' for all threads. + + A thread can set a key's value using 'OCIThreadKeySet()'. A thread can + get a key's value using 'OCIThreadKeyGet()'. + + The OCIThread key functions will save and retrieve data SPECIFIC TO THE + THREAD. When clients maintain a pool of threads and assign the threads to + different tasks, it *may not* be appropriate for a task to use OCIThread + key functions to save data associated with it. Here is a scenario of how + things can fail: A thread is assigned to execute the initialization of a + task. During the initialization, the task stored some data related to it + in the thread using OCIThread key functions. After the initialization, + the thread is returned back to the threads pool. Later, the threads pool + manager assigned another thread to perform some operations on the task, + and the task needs to retrieve those data it stored earlier in + initialization. Since the task is running in another thread, it will not + be able to retrieve the same data back! Applications that use thread + pools should be aware of this and be cautious when using OCIThread key + functions. + + +1.2.1.3 OCIThreadKeyDestFunc - OCIThread Key Destructor Function Type +------------------------------------------------------------------------ + + This is the type of a pointer to a key's destructor routine. Keys can be + associated with a destructor routine when they are created (see + 'OCIThreadKeyInit()'). + + A key's destructor routine will be called whenever a thread that has a + non-NULL value for the key terminates. + + The destructor routine returns nothing and takes one parameter. The + parameter will be the value that was set for key when the thread + terminated. + + The destructor routine is guaranteed to be called on a thread's value + in the key after the termination of the thread and before process + termination. No more precise guarantee can be made about the timing + of the destructor routine call; thus no code in the process may assume + any post-condition of the destructor routine. In particular, the + destructor is not guaranteed to execute before a join call on the + terminated thread returns. + + +1.2.1.4 OCIThreadId - OCIThread Thread ID +-------------------------------------------- + + Type 'OCIThreadId' is the type that will be used to identify a thread. + At any given time, no two threads will ever have the same 'OCIThreadId'. + However, 'OCIThreadId' values can be recycled; i.e., once a thread dies, + a new thread may be created that has the same 'OCIThreadId' as the one + that died. In particular, the thread ID must uniquely identify a thread + T within a process, and it must be consistent and valid in all threads U + of the process for which it can be guaranteed that T is running + concurrently with U. The thread ID for a thread T must be retrievable + within thread T. This will be done via OCIThreadIdGet(). + + The 'OCIThreadId' type supports the concept of a NULL thread ID: the NULL + thread ID will never be the same as the ID of an actual thread. + + + +1.2.2 Function prototypes for passive primitives +-------------------------------------------------- + +1.2.2.1 Mutex functions +------------------------- + + OCIThreadMutexInit - OCIThread MuteX Initialize + ----------------------------------------------- + + Description + + This allocate and initializes a mutex. All mutexes must be + initialized prior to use. + + Prototype + + sword OCIThreadMutexInit(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + mutex(OUT): The mutex to initialize. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + Multiple threads must not initialize the same mutex simultaneously. + Also, a mutex must not be reinitialized until it has been destroyed (see + 'OCIThreadMutexDestroy()'). + + OCIThreadMutexDestroy - OCIThread MuteX Destroy + ----------------------------------------------- + + Description + + This destroys and deallocate a mutex. Each mutex must be destroyed + once it is no longer needed. + + Prototype + + sword OCIThreadMutexDestroy(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + mutex(IN/OUT): The mutex to destroy. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is not legal to destroy a mutex that is uninitialized or is currently + held by a thread. The destruction of a mutex must not occur concurrently + with any other operations on the mutex. A mutex must not be used after + it has been destroyed. + + + OCIThreadMutexAcquire - OCIThread MuteX Acquire + ----------------------------------------------- + + Description + + This acquires a mutex for the thread in which it is called. If the mutex + is held by another thread, the calling thread is blocked until it can + acquire the mutex. + + Prototype + + sword OCIThreadMutexAcquire(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error, it is + recorded in err and this function returns OCI_ERROR. + Diagnostic information can be obtained by calling + OCIErrorGet(). + + mutex(IN/OUT): The mutex to acquire. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to attempt to acquire an uninitialized mutex. + + This function's behavior is undefined if it is used by a thread to + acquire a mutex that is already held by that thread. + + + + OCIThreadMutexRelease - OCIThread MuteX Release + ----------------------------------------------- + + Description + + This releases a mutex. If there are any threads blocked on the mutex, + one of them will acquire it and become unblocked. + + Prototype + + sword OCIThreadMutexRelease(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + mutex(IN/OUT): The mutex to release. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to attempt to release an uninitialized mutex. It is also + illegal for a thread to release a mutex that it does not hold. + + + OCIThreadKeyInit - OCIThread KeY Initialize + ------------------------------------------- + + Description + + This creates a key. Each call to this routine allocate and generates + a new key that is distinct from all other keys. + + Prototype + + sword OCIThreadKeyInit(void *hndl, OCIError *err, OCIThreadKey **key, + OCIThreadKeyDestFunc destFn); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(OUT): The 'OCIThreadKey' in which to create the new key. + + destFn(IN): The destructor for the key. NULL is permitted. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + Once this function executes successfully, a pointer to an allocated and + initialized key is return. That key can be used with 'OCIThreadKeyGet()' + and 'OCIThreadKeySet()'. The initial value of the key will be 'NULL' for + all threads. + + It is illegal for this function to be called more than once to create the + same key (i.e., to be called more than once with the same value for the + 'key' parameter). + + If the 'destFn' parameter is not NULL, the routine pointed to by 'destFn' + will be called whenever a thread that has a non-NULL value for the key + terminates. The routine will be called with one parameter. The + parameter will be the key's value for the thread at the time at which the + thread terminated. + If the key does not need a destructor function, pass NULL for 'destFn'. + + + OCIThreadKeyDestroy - OCIThread KeY DESTROY + ------------------------------------------- + + Description + + Destroy and deallocate the key pointed to by 'key'. + + Prototype + + sword OCIThreadKeyDestroy(void *hndl, OCIError *err, + OCIThreadKey **key); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(IN/OUT): The 'OCIThreadKey' in which to destroy the key. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + This is different from the destructor function callback passed to the + key create routine. This new destroy function 'OCIThreadKeyDestroy' is + used to terminate any resources OCI THREAD acquired when it created + 'key'. [The 'OCIThreadKeyDestFunc' callback type is a key VALUE + destructor; it does in no way operate on the key itself.] + + This must be called once the user has finished using the key. Not + calling the key destroy function may result in memory leaks. + + + + +1.2.2.2 Thread Key operations +------------------------------- + + OCIThreadKeyGet - OCIThread KeY Get value + ----------------------------------------- + + Description + + This gets the calling thread's current value for a key. + + Prototype + + sword OCIThreadKeyGet(void *hndl, OCIError *err, OCIThreadKey *key, + void **pValue); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(IN): The key. + + pValue(IN/OUT): The location in which to place the thread-specific + key value. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to use this function on a key that has not been created + using 'OCIThreadKeyInit()'. + + If the calling thread has not yet assigned a value to the key, 'NULL' is + placed in the location pointed to by 'pValue'. + + + OCIThreadKeySet - OCIThread KeY Set value + ----------------------------------------- + + Description + + This sets the calling thread's value for a key. + + Prototype + + sword OCIThreadKeySet(void *hndl, OCIError *err, OCIThreadKey *key, + void *value); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(IN/OUT): The key. + + value(IN): The thread-specific value to set in the key. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to use this function on a key that has not been created + using 'OCIThreadKeyInit()'. + +1.2.2.3 Thread Id +-------------------- + + OCIThreadIdInit - OCIThread Thread Id INITialize + -------------------------------------------------- + + Description + + Allocate and initialize the thread id 'tid'. + + Prototype + + sword OCIThreadIdInit(void *hndl, OCIError *err, OCIThreadId **tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid (OUT): Pointer to the thread ID to initialize. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + + OCIThreadIdDestroy - OCIThread Thread Id DESTROY + -------------------------------------------------- + + Description + + Destroy and deallocate the thread id 'tid'. + + Prototype + + sword OCIThreadIdDestroy(void *hndl, OCIError *err, OCIThreadId **tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid(IN/OUT): Pointer to the thread ID to destroy. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Note + + 'tid' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdSet - OCIThread Thread Id Set + ----------------------------------------- + + Description + + This sets one 'OCIThreadId' to another. + + Prototype + + sword OCIThreadIdSet(void *hndl, OCIError *err, + OCIThreadId *tidDest, + OCIThreadId *tidSrc); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tidDest(OUT): This should point to the location of the 'OCIThreadId' + to be set to. + + tidSrc(IN): This should point to the 'OCIThreadId' to set from. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'tid' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdSetNull - OCIThread Thread Id Set Null + --------------------------------------------------------- + + Description + + This sets the NULL thread ID to a given 'OCIThreadId'. + + Prototype + + sword OCIThreadIdSetNull(void *hndl, OCIError *err, + OCIThreadId *tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error, it is + recorded in err and this function returns OCI_ERROR. + Diagnostic information can be obtained by calling + OCIErrorGet(). + + tid(OUT): This should point to the 'OCIThreadId' in which to put + the NULL thread ID. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'tid' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdGet - OCIThread Thread Id Get + ------------------------------------------ + + Description + + This retrieves the 'OCIThreadId' of the thread in which it is called. + + Prototype + + sword OCIThreadIdGet(void *hndl, OCIError *err, + OCIThreadId *tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid(OUT): This should point to the location in which to place the + ID of the calling thread. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'tid' should be initialized by OCIThreadIdInit(). + + When OCIThread is used in a single-threaded environment, + OCIThreadIdGet() will always place the same value in the location + pointed to by 'tid'. The exact value itself is not important. The + important thing is that it is not the same as the NULL thread ID and + that it is always the same value. + + + OCIThreadIdSame - OCIThread Thread Ids Same? + ---------------------------------------------- + + Description + + This determines whether or not two 'OCIThreadId's represent the same + thread. + + Prototype + + sword OCIThreadIdSame(void *hndl, OCIError *err, + OCIThreadId *tid1, OCIThreadId *tid2, + boolean *result); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid1(IN): Pointer to the first 'OCIThreadId'. + + tid2(IN): Pointer to the second 'OCIThreadId'. + + result(IN/OUT): Pointer to the result. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + If 'tid1' and 'tid2' represent the same thread, 'result' is set to TRUE. + Otherwise, 'result' is set to FALSE. + + 'result' is set to TRUE if both 'tid1' and 'tid2' are the NULL thread ID. + + 'ti1d' and 'tid2' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdNull - OCIThread Thread Id NULL? + --------------------------------------------- + + Description + + This determines whether or not a given 'OCIThreadId' is the NULL thread + ID. + + Prototype + + sword OCIThreadIdNull(void *hndl, OCIError *err, + OCIThreadId *tid, + boolean *result); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid(IN): Pointer to the 'OCIThreadId' to check. + + result(IN/OUT): Pointer to the result. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + If 'tid' is the NULL thread ID, 'result' is set to TRUE. Otherwise, + 'result' is set to FALSE. + + 'tid' should be initialized by OCIThreadIdInit(). + + +1.3 Active Threading Primitives +================================= + +The active threading primitives deal with the manipulation of actual +threads. Because the specifications of most of these primitives require +that it be possible to have multiple threads, they work correctly only in +the enabled OCIThread; In the disabled OCIThread, they always return +failure. The exception is OCIThreadHandleGet(); it may be called in a +single-threaded environment, in which case it will have no effect. + +Active primitives should only be called by code running in a multi-threaded +environment. You can call OCIThreadIsMulti() to determine whether the +environment is multi-threaded or single-threaded. + + +1.3.1 Types +-------------- + +1.3.1.1 OCIThreadHandle - OCIThread Thread Handle +------------------------------------------------------ + + Type 'OCIThreadHandle' is used to manipulate a thread in the active + primitives: OCIThreadJoin()and OCIThreadClose(). A thread handle opened by + OCIThreadCreate() must be closed in a matching call to + OCIThreadClose(). A thread handle is invalid after the call to + OCIThreadClose(). + + The distinction between a thread ID and a thread handle in OCIThread usage + follows the distinction between the thread ID and the thread handle on + Windows NT. On many platforms, the underlying native types are the same. + + +1.3.2 Functions +------------------ + + OCIThreadHndInit - OCIThread HaNDle Initialize + ---------------------------------------------- + + Description + + Allocate and initialize the thread handle. + + Prototype + + sword OCIThreadHndInit(void *hndl, OCIError *err, + OCIThreadHandle **thnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + thnd(OUT): The address of pointer to the thread handle to initialize. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + + OCIThreadHndDestroy - OCIThread HaNDle Destroy + ---------------------------------------------- + + Description + + Destroy and deallocate the thread handle. + + Prototype + + sword OCIThreadHndDestroy(void *hndl, OCIError *err, + OCIThreadHandle **thnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + thnd(IN/OUT): The address of pointer to the thread handle to destroy. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + + OCIThreadCreate - OCIThread Thread Create + ----------------------------------------- + + Description + + This creates a new thread. + + Prototype + + sword OCIThreadCreate(void *hndl, OCIError *err, + void (*start)(void *), void *arg, + OCIThreadId *tid, OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + start(IN): The function in which the new thread should begin + execution. + + arg(IN): The argument to give the function pointed to by 'start'. + + tid(IN/OUT): If not NULL, gets the ID for the new thread. + + tHnd(IN/OUT): If not NULL, gets the handle for the new thread. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + The new thread will start by executing a call to the function pointed + to by 'start' with the argument given by 'arg'. When that function + returns, the new thread will terminate. The function should not + return a value and should accept one parameter, a 'void *'. + + The call to OCIThreadCreate() must be matched by a call to + OCIThreadClose() if and only if tHnd is non-NULL. + + If tHnd is NULL, a thread ID placed in *tid will not be valid in the + calling thread because the timing of the spawned thread's termination + is unknown. + + 'tid' should be initialized by OCIThreadIdInit(). + + 'thnd' should be initialized by OCIThreadHndInit(). + + + + OCIThreadJoin - OCIThread Thread Join + ------------------------------------- + + Description + + This function allows the calling thread to 'join' with another thread. + It blocks the caller until the specified thread terminates. + + Prototype + + sword OCIThreadJoin(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tHnd(IN): The 'OCIThreadHandle' of the thread to join with. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + The result of multiple threads all trying to join with the same thread is + undefined. + + + OCIThreadClose - OCIThread Thread Close + --------------------------------------- + + Description + + This function should be called to close a thread handle. + + Prototype + + sword OCIThreadClose(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tHnd(IN/OUT): The OCIThread thread handle to close. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + Both thread handle and the thread ID that was returned by the same call + to OCIThreadCreate() are invalid after the call to OCIThreadClose(). + + + + OCIThreadHandleGet - OCIThread Thread Get Handle + ------------------------------------------------ + + Description + + Retrieve the 'OCIThreadHandle' of the thread in which it is called. + + Prototype + + sword OCIThreadHandleGet(void *hndl, OCIError *err, + OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tHnd(IN/OUT): If not NULL, the location to place the thread + handle for the thread. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + The thread handle 'tHnd' retrieved by this function must be closed + with OCIThreadClose() and destroyed by OCIThreadHndDestroy() after it + is used. + + + + +1.4 Using OCIThread +===================== + +This section summarizes some of the more important details relating to the use +of OCIThread. + + * Process initialization + + OCIThread only requires that the process initialization function + ('OCIThreadProcessInit()') be called when OCIThread is being used in a + multi-threaded application. Failing to call 'OCIThreadProcessInit()' in + a single-threaded application is not an error. + + * OCIThread initialization + + Separate calls to 'OCIThreadInit()' will all return the same OCIThread + context. + + Also, remember that each call to 'OCIThreadInit()' must eventually be + matched by a call to 'OCIThreadTerm()'. + + * Active vs. Passive Threading primitives + + OCIThread client code written without using any active primitives can be + compiled and used without change on both single-threaded and + multi-threaded platforms. + + OCIThread client code written using active primitives will only work + correctly on multi-threaded platforms. In order to write a version of the + same application to run on single-threaded platform, it is necessary to + branch the your code, whether by branching versions of the source file or + by branching at runtime with the OCIThreadIsMulti() call. + +******************************************************************************/ + +/***************************************************************************** + ACTUAL PROTOTYPE DECLARATIONS +******************************************************************************/ + +void OCIThreadProcessInit(); + +sword OCIThreadInit(void *hndl, OCIError *err); + +sword OCIThreadTerm(void *hndl, OCIError *err); + +boolean OCIThreadIsMulti(); + +sword OCIThreadMutexInit(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + +sword OCIThreadMutexDestroy(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + +sword OCIThreadMutexAcquire(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + +sword OCIThreadMutexRelease(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + +sword OCIThreadKeyInit(void *hndl, OCIError *err, OCIThreadKey **key, + OCIThreadKeyDestFunc destFn); + +sword OCIThreadKeyDestroy(void *hndl, OCIError *err, + OCIThreadKey **key); + +sword OCIThreadKeyGet(void *hndl, OCIError *err, OCIThreadKey *key, + void **pValue); + +sword OCIThreadKeySet(void *hndl, OCIError *err, OCIThreadKey *key, + void *value); + +sword OCIThreadIdInit(void *hndl, OCIError *err, OCIThreadId **tid); + +sword OCIThreadIdDestroy(void *hndl, OCIError *err, OCIThreadId **tid); + +sword OCIThreadIdSet(void *hndl, OCIError *err, + OCIThreadId *tidDest, OCIThreadId *tidSrc); + +sword OCIThreadIdSetNull(void *hndl, OCIError *err, OCIThreadId *tid); + +sword OCIThreadIdGet(void *hndl, OCIError *err, OCIThreadId *tid); + +sword OCIThreadIdSame(void *hndl, OCIError *err, + OCIThreadId *tid1, OCIThreadId *tid2, + boolean *result); + +sword OCIThreadIdNull(void *hndl, OCIError *err, + OCIThreadId *tid, boolean *result); + +sword OCIThreadHndInit(void *hndl, OCIError *err, OCIThreadHandle **thnd); + +sword OCIThreadHndDestroy(void *hndl, OCIError *err, OCIThreadHandle **thnd); + +sword OCIThreadCreate(void *hndl, OCIError *err, + void (*start)(void *), void *arg, + OCIThreadId *tid, OCIThreadHandle *tHnd); + +sword OCIThreadJoin(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + +sword OCIThreadClose(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + +sword OCIThreadHandleGet(void *hndl, OCIError *err, OCIThreadHandle *tHnd); +/*----------------- End OCI Thread interface Extensions ---------------------*/ + +/*------------------ Begin OCI Row Callback Interfaces ----------------------*/ + +typedef sword (*OCIBindRowCallback)(void *ctx); +typedef sword (*OCIFetchRowCallback)(void *ctx); + +/*------------------ Begin OCI Row Callback Interfaces ----------------------*/ + +/*--------------- Begin OCI Client Notification Interfaces ------------------*/ + +typedef ub4 (*OCISubscriptionNotify)(void *ctx, OCISubscription *subscrhp, + void *pay, ub4 payl, + void *desc, ub4 mode); + +sword OCISubscriptionRegister(OCISvcCtx *svchp, OCISubscription **subscrhpp, + ub2 count, OCIError *errhp, ub4 mode); + + +sword OCISubscriptionPost(OCISvcCtx *svchp, OCISubscription **subscrhpp, + ub2 count, OCIError *errhp, ub4 mode); + +sword OCISubscriptionUnRegister(OCISvcCtx *svchp, OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +sword OCISubscriptionDisable(OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +sword OCISubscriptionEnable(OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +/*------------------- End OCI Publish/Subscribe Interfaces ------------------*/ + +/*----------------- Extensions to Datetime interfaces -----------------------*/ +/*--------------------- Actual Prototypes -----------------------------------*/ +sword OCIDateTimeGetTime(void *hndl, OCIError *err, OCIDateTime *datetime, + ub1 *hr, ub1 *mm, ub1 *ss, ub4 *fsec); + +sword OCIDateTimeGetDate(void *hndl, OCIError *err, const OCIDateTime *date, + sb2 *yr, ub1 *mnth, ub1 *dy ); + +sword OCIDateTimeGetTimeZoneOffset(void *hndl,OCIError *err, + const OCIDateTime *datetime, + sb1 *hr,sb1 *mm); + +sword OCIDateTimeConstruct(void *hndl,OCIError *err,OCIDateTime *datetime, + sb2 yr,ub1 mnth,ub1 dy,ub1 hr,ub1 mm,ub1 ss,ub4 fsec, + OraText *timezone,size_t timezone_length); + +sword OCIDateTimeSysTimeStamp(void *hndl, OCIError *err, + OCIDateTime *sys_date ); + +sword OCIDateTimeAssign(void *hndl, OCIError *err, const OCIDateTime *from, + OCIDateTime *to); + +sword OCIDateTimeToText(void *hndl, OCIError *err, const OCIDateTime *date, + const OraText *fmt, ub1 fmt_length, ub1 fsprec, + const OraText *lang_name, size_t lang_length, + ub4 *buf_size, OraText *buf ); + +sword OCIDateTimeFromText(void *hndl, OCIError *err, const OraText *date_str, + size_t dstr_length, const OraText *fmt, ub1 fmt_length, + const OraText *lang_name, size_t lang_length, OCIDateTime *date ); + +sword OCIDateTimeCompare(void *hndl, OCIError *err, const OCIDateTime *date1, + const OCIDateTime *date2, sword *result ); + +sword OCIDateTimeCheck(void *hndl, OCIError *err, const OCIDateTime *date, + ub4 *valid ); + +sword OCIDateTimeConvert(void *hndl, OCIError *err, OCIDateTime *indate, + OCIDateTime *outdate); + +sword OCIDateTimeSubtract(void *hndl, OCIError *err, OCIDateTime *indate1, + OCIDateTime *indate2, OCIInterval *inter); + +sword OCIDateTimeIntervalAdd(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); + +sword OCIDateTimeIntervalSub(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); + +sword OCIIntervalSubtract(void *hndl, OCIError *err, OCIInterval *minuend, + OCIInterval *subtrahend, OCIInterval *result ); + +sword OCIIntervalAdd(void *hndl, OCIError *err, OCIInterval *addend1, + OCIInterval *addend2, OCIInterval *result ); + +sword OCIIntervalMultiply(void *hndl, OCIError *err, const OCIInterval *inter, + OCINumber *nfactor, OCIInterval *result ); + +sword OCIIntervalDivide(void *hndl, OCIError *err, OCIInterval *dividend, + OCINumber *divisor, OCIInterval *result ); + +sword OCIIntervalCompare(void *hndl, OCIError *err, OCIInterval *inter1, + OCIInterval *inter2, sword *result ); + +sword OCIIntervalFromNumber(void *hndl, OCIError *err, OCIInterval *inter, + OCINumber *number); + +sword OCIIntervalFromText( void *hndl, OCIError *err, const OraText *inpstr, + size_t str_len, OCIInterval *result ); + +sword OCIIntervalToText( void *hndl, OCIError *err, const OCIInterval *inter, + ub1 lfprec, ub1 fsprec, + OraText *buffer, size_t buflen, size_t *resultlen ); + +sword OCIIntervalToNumber(void *hndl, OCIError *err,const OCIInterval *inter, + OCINumber *number); + +sword OCIIntervalCheck(void *hndl, OCIError *err, const OCIInterval *interval, + ub4 *valid ); + +sword OCIIntervalAssign(void *hndl, OCIError *err, const OCIInterval *ininter, + OCIInterval *outinter ); + +sword OCIIntervalSetYearMonth(void *hndl, OCIError *err, sb4 yr, sb4 mnth, + OCIInterval *result ); + +sword OCIIntervalGetYearMonth(void *hndl, OCIError *err, sb4 *yr, sb4 *mnth, + const OCIInterval *result ); + +sword OCIIntervalSetDaySecond(void *hndl, OCIError *err, sb4 dy, sb4 hr, + sb4 mm, sb4 ss, sb4 fsec, OCIInterval *result ); + +sword OCIIntervalGetDaySecond(void *hndl, OCIError *err, sb4 *dy, sb4 *hr, + sb4 *mm, sb4 *ss, sb4 *fsec, const OCIInterval *result ); + +sword OCIDateTimeToArray(void *hndl, OCIError *err, + const OCIDateTime *datetime, const OCIInterval *reftz, + ub1 *outarray, ub4 *len, ub1 fsprec); + +sword OCIDateTimeFromArray(void *hndl, OCIError *err, ub1 *inarray, ub4 len, + ub1 type, OCIDateTime *datetime, + const OCIInterval *reftz, ub1 fsprec); + +sword OCIDateTimeGetTimeZoneName(void *hndl, OCIError *err, + const OCIDateTime *datetime, + ub1 *buf, ub4 *buflen); + +sword OCIIntervalFromTZ(void *hndl, OCIError *err, const oratext *inpstring, + size_t str_len, OCIInterval *result); + +/*----------------- End Datetime interface Extensions -----------------------*/ + +/*----------------- Connection Pooling prototypes ---------------------------*/ +sword OCIConnectionPoolCreate(OCIEnv *envhp, OCIError *errhp, OCICPool *poolhp, + OraText **poolName, sb4 *poolNameLen, + const OraText *dblink, sb4 dblinkLen, + ub4 connMin, ub4 connMax, ub4 connIncr, + const OraText *poolUserName, sb4 poolUserLen, + const OraText *poolPassword, sb4 poolPassLen, + ub4 mode); + +sword OCIConnectionPoolDestroy(OCICPool *poolhp, + OCIError *errhp, ub4 mode); + +/*----------------- End Connection Pooling prototypes -----------------------*/ + +/*-------------------- Session Pooling prototypes ---------------------------*/ + +sword OCISessionPoolCreate (OCIEnv *envhp, OCIError *errhp, OCISPool *spoolhp, + OraText **poolName, ub4 *poolNameLen, + const OraText *connStr, ub4 connStrLen, + ub4 sessMin, ub4 sessMax, ub4 sessIncr, + OraText *userid, ub4 useridLen, + OraText *password, ub4 passwordLen, + ub4 mode); + +sword OCISessionPoolDestroy (OCISPool *spoolhp, + OCIError *errhp, + ub4 mode); + +sword OCISessionGet (OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + OCIAuthInfo *authhp, + OraText *poolName, ub4 poolName_len, + const OraText *tagInfo, ub4 tagInfo_len, + OraText **retTagInfo, ub4 *retTagInfo_len, + boolean *found, ub4 mode); + +sword OCISessionRelease (OCISvcCtx *svchp, OCIError *errhp, + OraText *tag, ub4 tag_len, + ub4 mode); + +/*-------------------- End Session Pooling prototypes -----------------------*/ + +/* --------------------- OCI Application Context --------------------------*/ + + +sword OCIAppCtxSet(void * sesshndl, void *nsptr, ub4 nsptrlen, + void *attrptr, ub4 attrptrlen, + void *valueptr, ub4 valueptrlen, + OCIError *errhp, ub4 mode); + +sword OCIAppCtxClearAll(void *sesshndl, void *nsptr, ub4 nsptrlen, + OCIError *errhp, ub4 mode); + +/*-------------------------------- OCIMemStats ------------------------------*/ +sword OCIMemStats(void *hndlp, OCIError *errhp, OCIEnv **envhp, + ub4 mode, ub4 mode1, oratext *tabname); + +/*-------------------------------- OCIPing ----------------------------------*/ +sword OCIPing (OCISvcCtx *svchp, OCIError *errhp, ub4 mode); + +/*----------------- Kerberos Authentication prototypes ----------------------*/ + +sword OCIKerbAttrSet(OCISession *trgthndlp, ub4 cred_use, ub1 *ftgt_ticket, + ub4 ticket_len, ub1 *session_key, ub4 skey_len, + ub2 ftgt_keytype, ub4 ftgt_ticket_flags, + sb4 ftgt_auth_time, sb4 ftgt_start_time, + sb4 ftgt_end_time, sb4 ftgt_renew_time, + oratext *ftgt_client_principal, + ub4 ftgt_client_principal_len, oratext *ftgt_client_realm, + ub4 ftgt_client_realm_len, OCIError *errhp); + +/*------------------- End Kerberos Authentication prototypes ----------------*/ + +/*------------------- Database Startup/Shutdown prototypes ------------------*/ + +sword OCIDBStartup (OCISvcCtx *svchp, + OCIError *errhp, + OCIAdmin *admhp, + ub4 mode, + ub4 flags); + +sword OCIDBShutdown(OCISvcCtx *svchp, + OCIError *errhp, + OCIAdmin *admhp, + ub4 mode); + +/*------------------ End Database Startup/Shutdown prototypes ---------------*/ + +/*----------------------- OCIClientVersion ------------------------------*/ +void OCIClientVersion(sword *major_version, + sword *minor_version, + sword *update_num, + sword *patch_num, + sword *port_update_num); +/*----------------------- End OCIClientVersion --------------------------*/ + +/*----------------------- HA Event prototypes ------------------------------*/ + +sword OCIInitEventHandle(OCIError *errhp, + OCIEvent *event, + text *str, + ub4 size); + +/*----------------------- End HA Event prototypes --------------------------*/ + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + /* the following functions are depracated and should not be used */ +#ifdef NEVER +sword OCIStmtBindByPos (OCIStmt *stmtp, OCIBind *bindp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, + ub2 dty, void *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + + +sword OCIStmtBindByName (OCIStmt *stmtp, OCIBind *bindp, OCIError *errhp, + const OraText *placeholder, sb4 placeh_len, void *valuep, + sb4 value_sz, ub2 dty, void *indp, ub2 *alenp, + ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode); + +sword ocidefn (OCIStmt *stmtp, OCIDefine *defnp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, ub2 dty, + void *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode); +#endif /* NEVER */ + +#endif /* OCIAP_ORACLE */ diff --git a/OCI/include/ociapr.h b/OCI/include/ociapr.h new file mode 100644 index 0000000..2f25c52 --- /dev/null +++ b/OCI/include/ociapr.h @@ -0,0 +1,155 @@ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ociapr.h + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + dsaha 05/19/00 - Fix lint + sgollapu 05/19/98 - Change text to OraText + dchatter 11/10/95 - add ognfd() - get native fd + lchidamb 04/06/95 - drop maxdsz from obindps/odefinps + slari 04/07/95 - add opinit + dchatter 03/08/95 - osetpi and ogetpi + lchidamb 12/09/94 - add obindps() and odefinps() + dchatter 03/06/95 - merge changes from branch 1.1.720.2 + dchatter 11/14/94 - merge changes from branch 1.1.720.1 + dchatter 02/08/95 - olog call; drop onblon + dchatter 10/31/94 - new functions for non-blocking oci + rkooi2 11/27/92 - Changing datatypes to agree with ocidef.h + rkooi2 10/26/92 - More portability mods + rkooi2 10/18/92 - Changed to agree with oci.c + sjain 03/16/92 - Creation +*/ +/* + * Declare the OCI functions. + * Prototype information is included. + * Use this header for ANSI C compilers. + */ + +#ifndef OCIAPR +#define OCIAPR + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN +#include +#endif + +/* + * Oci BIND (Piecewise or with Skips) + */ +sword obindps(struct cda_def *cursor, ub1 opcode, OraText *sqlvar, + sb4 sqlvl, ub1 *pvctx, sb4 progvl, + sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip, + ub4 maxsiz, ub4 *cursiz, + OraText *fmt, sb4 fmtl, sword fmtt); +sword obreak(struct cda_def *lda); +sword ocan (struct cda_def *cursor); +sword oclose(struct cda_def *cursor); +sword ocof (struct cda_def *lda); +sword ocom (struct cda_def *lda); +sword ocon (struct cda_def *lda); + + +/* + * Oci DEFINe (Piecewise or with Skips) + */ +sword odefinps(struct cda_def *cursor, ub1 opcode, sword pos,ub1 *bufctx, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sb4 fmtl, sword fmtt, + ub2 *rlen, ub2 *rcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip); +sword odessp(struct cda_def *cursor, OraText *objnam, size_t onlen, + ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t rsv2ln, + ub2 *ovrld, ub2 *pos, ub2 *level, OraText **argnam, + ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* mode, + ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *arrsiz); +sword odescr(struct cda_def *cursor, sword pos, sb4 *dbsize, + sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize, + sb2 *prec, sb2 *scale, sb2 *nullok); +sword oerhms (struct cda_def *lda, sb2 rcode, OraText *buf, + sword bufsiz); +sword oermsg (sb2 rcode, OraText *buf); +sword oexec (struct cda_def *cursor); +sword oexfet (struct cda_def *cursor, ub4 nrows, + sword cancel, sword exact); +sword oexn (struct cda_def *cursor, sword iters, sword rowoff); +sword ofen (struct cda_def *cursor, sword nrows); +sword ofetch (struct cda_def *cursor); +sword oflng (struct cda_def *cursor, sword pos, ub1 *buf, + sb4 bufl, sword dtype, ub4 *retl, sb4 offset); +sword ogetpi (struct cda_def *cursor, ub1 *piecep, void **ctxpp, + ub4 *iterp, ub4 *indexp); +sword oopt (struct cda_def *cursor, sword rbopt, sword waitopt); +sword opinit (ub4 mode); +sword olog (struct cda_def *lda, ub1* hda, + OraText *uid, sword uidl, + OraText *pswd, sword pswdl, + OraText *conn, sword connl, + ub4 mode); +sword ologof (struct cda_def *lda); +sword oopen (struct cda_def *cursor, struct cda_def *lda, + OraText *dbn, sword dbnl, sword arsize, + OraText *uid, sword uidl); +sword oparse (struct cda_def *cursor, OraText *sqlstm, sb4 sqllen, + sword defflg, ub4 lngflg); +sword orol (struct cda_def *lda); +sword osetpi (struct cda_def *cursor, ub1 piece, void *bufp, ub4 *lenp); + +void sqlld2 (struct cda_def *lda, OraText *cname, sb4 *cnlen); +void sqllda (struct cda_def *lda); + +/* non-blocking functions */ +sword onbset (struct cda_def *lda ); +sword onbtst (struct cda_def *lda ); +sword onbclr (struct cda_def *lda ); +sword ognfd (struct cda_def *lda, void *fdp); + + +/* + * OBSOLETE CALLS + */ + +/* + * OBSOLETE BIND CALLS + */ +sword obndra(struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz, + ub4 *cursiz, OraText *fmt, sword fmtl, sword fmtt); +sword obndrn(struct cda_def *cursor, sword sqlvn, ub1 *progv, + sword progvl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt); +sword obndrv(struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sword fmtl, sword fmtt); + +/* + * OBSOLETE DEFINE CALLS + */ +sword odefin(struct cda_def *cursor, sword pos, ub1 *buf, + sword bufl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt, ub2 *rlen, ub2 *rcode); + +/* older calls ; preferred equivalent calls above */ + +sword oname (struct cda_def *cursor, sword pos, sb1 *tbuf, + sb2 *tbufl, sb1 *buf, sb2 *bufl); +sword orlon (struct cda_def *lda, ub1 *hda, + OraText *uid, sword uidl, + OraText *pswd, sword pswdl, + sword audit); +sword olon (struct cda_def *lda, OraText *uid, sword uidl, + OraText *pswd, sword pswdl, sword audit); +sword osql3 (struct cda_def *cda, OraText *sqlstm, sword sqllen); +sword odsc (struct cda_def *cursor, sword pos, sb2 *dbsize, + sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf, + sb2 *bufl, sb2 *dsize); + +#endif /* OCIAPR */ diff --git a/OCI/include/ocidef.h b/OCI/include/ocidef.h new file mode 100644 index 0000000..9fde50b --- /dev/null +++ b/OCI/include/ocidef.h @@ -0,0 +1,886 @@ +/* Copyright (c) 1981, 2005, Oracle. All rights reserved. */ +/* Copyright (c) 1984, 2005, Oracle. All rights reserved. */ + +/* +NAME + ocidef +CONTENTS + Oracle Call Interface cursor area and LDA definitions +NOTES + none +OWNER + Oates +DATE + 09/07/82 +MODIFIED + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/25/03 - convert oci public api to ansi + csteinba 11/05/02 - bug 2521931: redefine OTYACL + aahluwal 06/03/02 - bug 2360115 + bpalaval 02/08/01 - Change text to oratext. + chliang 02/01/01 - fix olint error. + bpalaval 11/16/00 - Bug 1244685 : Fix ALTER CLUSTER issue.. + slari 11/08/00 - remove functions duplicated in ociapr.h + whe 09/01/99 - 976457:check __cplusplus for C++ code + skmishra 04/23/97 - Provide C++ compatibility + lchidamb 06/26/96 - put upidef.h, riddef.h within #ifndef + slari 06/12/96 - add ocigft_getFcnType + dchatter 11/10/95 - ocignfd - oci get native file descriptor + slari 05/11/95 - change OCIEVDEF/OCIEVTSF to UPIEVDEF/UPIEVTSF + dchatter 04/06/95 - add ifdef flags around OCI_flags + lchidamb 04/06/95 - drop maxdsz from ocibndps/ocidfnps + slari 04/07/95 - rename opinit to ocipin + slari 03/13/95 - thread safety changes + dchatter 03/08/95 - piece definitions OCI_*_PIECE + lchidamb 12/06/94 - add support for binding/defining with skips + dchatter 03/06/95 - merge changes from branch 1.12.720.1 + dchatter 02/06/95 - add defines for login mode parameters + dchatter 07/06/94 - Deleting CRSCHK, with refcursor, no way to set this + dchatter 06/13/94 - add a new LDA flag LDANBL + rkooi 11/18/92 - update ocidpr interface + mmoore 10/31/92 - add ocidpr + gpongrac 11/17/92 - fix oexfet prototype + sjain 01/03/92 - Add ocibra + rjenkins 11/04/91 - adding prototypes for oparse and oexfet + sjain 04/15/91 - Change ocistf proto + sjain 04/01/91 - Rearrange oty codes. Add new ones + Jain 12/03/90 - Add #define for new describe call + Jain 11/29/90 - Add new function code for the new oci calls + Mendels 01/20/89 - fix 19170: make ocitbl CONST_DATA + Kabcene 01/27/88 - change interfaces to match V5 + Navab 12/09/87 - add a parameter to ocierr call + Navab 11/30/87 - add ocierr, rename ocioer + Navab 10/08/87 - add prototypes for procedure declarations + Howard 09/07/87 - endif blah + Howard 05/11/87 - Add OTY types + Howard 04/27/87 - move ocldef defines here + Oates 10/15/85 - Add OCANCEL + Oates 09/30/85 - Implement ORA*Net + Oates 06/27/85 - Make datatype compatible with upidef.h + Andy 05/07/85 - delete CSRFBPIC +*/ + +#ifndef UPIDEF +#include +#endif + +#ifndef RIDDEF +#include +#endif + +#include + +#ifndef OCIDEF +#define OCIDEF + + +#define CSRCHECK 172 /* csrdef is a cursor */ +#define LDACHECK 202 /* csrdef is a login data area */ +struct csrdef +{ + sb2 csrrc; /* return code: v2 codes, v4 codes negative */ + ub2 csrft; /* function type */ + ub4 csrrpc; /* rows processed count */ + ub2 csrpeo; /* parse error offset */ + ub1 csrfc; /* function code */ + ub1 csrlfl; /* lda flag to indicate type of login */ + ub2 csrarc; /* actual untranslated return code */ + ub1 csrwrn; /* warning flags */ + ub1 csrflg; /* error action */ + sword csrcn; /* cursor number */ + riddef csrrid; /* rowid structure */ + sword csrose; /* os dependent error code */ + ub1 csrchk; /* check byte = CSRCHECK - in cursor */ + /* check byte = LDACHECK - in LDA */ + struct hstdef *csrhst; /* pointer to the hst */ +}; +typedef struct csrdef csrdef; +typedef struct csrdef ldadef; /* lda is the same as a csr */ + + +/* values for csrlfl */ +#define LDAFLG 1 /* ...via ologon */ +#define LDAFLO 2 /* ...via olon or orlon */ +#define LDANBL 3 /* ...nb logon in progress */ + +/* valuses for crsfc */ +#define csrfpa 2 /* ...OSQL */ +#define csrfex 4 /* ...OEXEC */ +#define csrfbi 6 /* ...OBIND */ +#define csrfdb 8 /* ...ODFINN */ +#define csrfdi 10 /* ...ODSRBN */ +#define csrffe 12 /* ...OFETCH */ +#define csrfop 14 /* ...OOPEN */ +#define csrfcl 16 /* ...OCLOSE */ +#define csrfds 22 /* ...ODSC */ +#define csrfnm 24 /* ...ONAME */ +#define csrfp3 26 /* ...OSQL3 */ +#define csrfbr 28 /* ...OBNDRV */ +#define csrfbx 30 /* ...OBNDRN */ +/*#defe csrfdf 32*/ /* ???? */ +#define csrfso 34 /* ...OOPT */ +#define csrfre 36 /* ...ORESUM */ +#define csrfbn 50 /* ...OBINDN */ +#define csrfca 52 /* ..OCANCEL */ +#define csrfsd 54 /* ..OSQLD */ +#define csrfef 56 /* ..OEXFEN */ +#define csrfln 58 /* ..OFLNG */ +#define csrfdp 60 /* ..ODSCSP */ +#define csrfba 62 /* ..OBNDRA */ +#define csrfbps 63 /*..OBINDPS */ +#define csrfdps 64 /*..ODEFINPS */ +#define csrfgpi 65 /* ...OGETPI */ +#define csrfspi 66 /* ...OSETPI */ + +/* values for csrwrn */ +#define CSRWANY 0x01 /* there is a warning flag set */ +#define CSRWTRUN 0x02 /* a data item was truncated */ +#define CSRWNVIC 0x04 /* NULL values were used in an aggregate function */ +#define CSRWITCE 0x08 /* column count not equal to into list count */ +#define CSRWUDNW 0x10 /* update or delete without where clause */ +#define CSRWRSV0 0x20 +#define CSRWROLL 0x40 /* rollback required */ +#define CSRWRCHG 0x80 /* change after query start on select for update */ + +/* values fro csrflg */ +#define CSRFSPND 0x01 /* current operation suspended */ +#define CSRFATAL 0x02 /* fatal operation: transaction rolled back */ +#define CSRFBROW 0x04 /* current row backed out */ +#define CSRFREFC 0x08 /* ref cursor type CRSCHK disabled for this cursor */ +#define CSRFNOAR 0x10 /* ref cursor type binds, so no array bind/execute */ + +/* define function codes; in order of octdef.h */ +#define OTYCTB 1 /* CREATE TABLE */ +#define OTYSER 2 /* set role */ +#define OTYINS 3 /* INSERT */ +#define OTYSEL 4 /* SELECT */ +#define OTYUPD 5 /* UPDATE */ +#define OTYDRO 6 /* drop role */ +#define OTYDVW 7 /* DROP VIEW */ + /* once was validate index */ + /* once was create partition */ + /* once was alter partition */ +#define OTYDTB 8 /* DROP TABLE */ + /* once was alter space */ + /* once was drop space */ +#define OTYDEL 9 /* DELETE */ +#define OTYCVW 10 /* create view */ +#define OTYDUS 11 /* drop user */ +#define OTYCRO 12 /* create role */ +#define OTYCSQ 13 /* create sequence */ +#define OTYASQ 14 /* alter sequence */ +#define OTYACL 15 /* alter cluster */ +#define OTYDSQ 16 /* drop sequence */ +#define OTYCSC 17 /* create schema */ +#define OTYCCL 18 /* CREATE CLUSTER */ + /* once was alter cluster */ +#define OTYCUS 19 /* create user */ +#define OTYCIX 20 /* CREATE INDEX */ +#define OTYDIX 21 /* DROP INDEX */ +#define OTYDCL 22 /* DROP CLUSTER */ +#define OTYVIX 23 /* validate index */ +#define OTYCPR 24 /* create procedure */ +#define OTYAPR 25 /* alter procedure */ +#define OTYATB 26 /* alter table */ + /* once was evaluate */ +#define OTYXPL 27 /* explain */ +#define OTYGRA 28 /* grant */ +#define OTYREV 29 /* revoke */ +#define OTYCSY 30 /* create synonym */ +#define OTYDSY 31 /* drop synonym */ +#define OTYASY 32 /* alter system switch log */ +#define OTYSET 33 /* set transaction */ +#define OTYPLS 34 /* pl/sql execute */ +#define OTYLTB 35 /* lock */ +#define OTYNOP 36 /* noop */ +#define OTYRNM 37 /* rename */ +#define OTYCMT 38 /* comment */ +#define OTYAUD 39 /* audit */ +#define OTYNOA 40 /* no audit */ +#define OTYAIX 41 /* ALTER INDEX */ +#define OTYCED 42 /* create external database */ +#define OTYDED 43 /* drop external database */ +#define OTYCDB 44 /* create database */ +#define OTYADB 45 /* alter database */ +#define OTYCRS 46 /* create rollback segment */ +#define OTYARS 47 /* alter rollback segment */ +#define OTYDRS 48 /* drop rollback segment */ +#define OTYCTS 49 /* create tablespace */ +#define OTYATS 50 /* alter tablespace */ +#define OTYDTS 51 /* drop tablespace */ +#define OTYASE 52 /* alter session */ +#define OTYAUR 53 /* alter user */ +#define OTYCWK 54 /* commit (work) */ +#define OTYROL 55 /* rollback */ +#define OTYSPT 56 /* savepoint */ + +/* For number greater than 56 the the type is the same as defined in +** octdef.h for that number. So for completion look at octdef.h +*/ + +#define OTYDEV OTYCVW /* old DEFINE VIEW = create view */ + +/* FUNCTION CODES */ +#define OCLFPA 2 /* parse - OSQL */ +#define OCLFEX 4 /* execute - OEXEC */ +#define OCLFBI 6 /* BIND by name - OBIND */ +#define OCLFDB 8 /* define buffer - ODEFIN */ +#define OCLFDI 10 /* describe item - ODSC */ +#define OCLFFE 12 /* fetch - OFETCH */ +#define OCLFOC 14 /* open cursor - OOPEN */ +# define OCLFLI OCLFOC /* old name for open cursor - OOPEN */ +#define OCLFCC 16 /* close cursor - OCLOSE */ +# define OCLFLO OCLFCC /* old name for close cursor - OCLOSE */ +#define OCLFDS 22 /* describe - ODSC */ +#define OCLFON 24 /* get table and column names - ONAME */ +#define OCLFP3 26 /* parse - OSQL3 */ +#define OCLFBR 28 /* bind reference by name - OBNDRV */ +#define OCLFBX 30 /* bind referecne numeric - OBNDRN */ +#define OCLFSO 34 /* special function - OOPT */ +#define OCLFRE 36 /* resume - ORESUM */ +#define OCLFBN 50 /* bindn */ +#define OCLFMX 52 /* maximum function number */ + +#ifdef NEVER /* unused codes */ +# define OCLFLK 18 /* open for kernel operations */ +# define OCLFEK 20 /* execute kernel operations */ +# define OCLFOK 22 /* kernel close */ +# define OCLFIN 28 /* logon to oracle */ +# define OCLFOF 30 /* logoff from oracle */ +# define OCLFAX 32 /* allocate a context area */ +# define OCLFPI 34 /* page in context area */ +# define OCLFIS 36 /* special system logon */ +# define OCLFCO 38 /* cancel the current operation */ +# define OCLFGI 40 /* get database id */ +# define OCLFJN 42 /* journal operation */ +# define OCLFCL 44 /* cleanup prior execute operation */ +# define OCLFMC 46 /* map a cursor area */ +# define OCLFUC 48 /* unmap cursor and restore user maping */ +#endif /*NEVER *//* obsolete codes */ + + +/* values for ocimode in ocipin call */ + +#define OCIEVDEF UPIEVDEF /* default : non-thread safe enivronment */ +#define OCIEVTSF UPIEVTSF /* thread-safe environment */ + + +/* OCIL* flags used to determine the mode of login, using ocilog(). +** Currently defined only for non-blocking and thread-safe logins. +*/ + +#define OCILMDEF UPILMDEF /* default, regular login */ +#define OCILMNBL UPILMNBL /* non-blocking logon */ +#define OCILMESY UPILMESY /* thread safe but external sync */ +#define OCILMISY UPILMISY /* internal sync, we do it */ +#define OCILMTRY UPILMTRY /* try to, but do not block on mutex */ + + +/* + * since sqllib uses both ocidef and ocidfn the following defines + * need to be guarded + */ +#ifndef OCI_FLAGS +#define OCI_FLAGS + +/* OCI_*_PIECE defines the piece types that are returned or set +*/ + +#define OCI_ONE_PIECE UPI_ONE_PIECE /* there or this is the only piece */ +#define OCI_FIRST_PIECE UPI_FIRST_PIECE /* the first of many pieces */ +#define OCI_NEXT_PIECE UPI_NEXT_PIECE /* the next of many pieces */ +#define OCI_LAST_PIECE UPI_LAST_PIECE /* the last piece of this column */ +#endif + +/* +** OCITAB: define return code pairs for version 2 to 3 conversions +*/ +struct ocitab +{ + sb2 ocitv3; /* Version 3/4 return code */ + sb2 ocitv2; /* Version 2 equivalent return code */ +}; +typedef struct ocitab ocitab; + +externref const ocitab ocitbl[]; + +/* macros to check cursors and LDA's. */ +/* macros to set error codes */ + +# define CRSCHK(c) if ((c->csrchk != CSRCHECK)\ + && !bit(c->csrflg, CSRFREFC))\ + return(ocir32(c, OER(1001))) +# define ldaerr(l, e) ( l->csrrc = (sb2)(-( l->csrarc = (ub2)(e)) ) ) +# define LDACHK(l) if (l->csrchk != LDACHECK) \ + return(ldaerr(l, OER(1001))) + + +/************************************************/ +/* OCI PROCEDURE DECLARATIONS */ +/************************************************/ + + + + +/*****************************/ +/* Database logon/logout */ +/*****************************/ +sword ocilog( ldadef *lda, struct hstdef *hst, oratext *uid, sword uidl, + oratext *psw, sword pswl, oratext* conn, sword connl, + ub4 mode ); +sword ocilon( ldadef *lda, oratext *uid, sword uidl, oratext *psw, + sword pswl, sword audit ); +sword ocilgi( ldadef *lda, sb2 areacount ); +sword ocirlo( ldadef *lda, struct hstdef *hst, oratext *uid, sword uidl, + oratext *psw, sword pswl, sword audit ); + /* ocilon - logon to oracle + ** ocilgi - version 2 compatible ORACLE logon call. + ** no login to ORACLE is performed: the LDA is initialized + ** ocirlo - version 5 compatible ORACLE Remote Login call, + ** oracle login is executed. + ** lda - pointer to ldadef + ** uid - user id [USER[/PASSWORD]] + ** uidl - length of uid, if -1 strlen(uid) is used + ** psw - password string; ignored if specified in uid + ** pswl - length of psw, if -1 strlen(psw) is used + ** audit - is not supported; the only permissible value is 0 + ** areacount - unused + */ + +sword ocilof( ldadef *lda ); + /* + ** ocilof - disconnect from ORACLE + ** lda - pointer to ldadef + */ + + +/*********************/ +/* Error Messages */ +/*********************/ +sword ocierr( ldadef *lda, sb2 rcode, oratext *buffer, sword bufl ); +sword ocidhe( sb2 rcode, oratext *buffer ); + /* + ** Move the text explanation for an ORACLE error to a user defined buffer + ** ocierr - will return the message associated with the hstdef stored + ** in the lda. + ** ocidhe - will return the message associated with the default host. + ** lda - lda associated with the login session + ** rcode - error code as returned by V3 call interface + ** buffer - address of a user buffer of at least 132 characters + */ + + +/***********************/ +/* Cursor Open/Close */ +/***********************/ +sword ociope( struct csrdef *cursor, ldadef *lda, oratext *dbn, sword dbnl, + sword areasize, oratext *uid, sword uidl ); + +sword ociclo( struct csrdef *cursor ); + /* + ** open or close a cursor. + ** cursor - pointer to csrdef + ** ldadef - pointer to ldadef + ** dbn - unused + ** dbnl - unused + ** areasize - if (areasize == -1) areasize <- system default initial size + ** else if (areasize IN [1..256]) areasize <- areasize * 1024; + ** most applications should use the default size since context + ** areas are extended as needed until memory is exhausted. + ** uid - user id + ** uidl - userid length + */ + +/***********************************/ +/* CONTROL AND OPTIONS */ +/***********************************/ +sword ocibre( ldadef *lda ); + /* + ** ocibrk - Oracle Call Interface send BReaK Sends a break to + ** oracle. If oracle is active, the current operation is + ** cancelled. May be called asynchronously. DOES NOT SET + ** OERRCD in the hst. This is because ocibrk may be called + ** asynchronously. Callers must test the return code. + ** lda - pointer to a ldadef + */ + +sword ocican( struct csrdef *cursor ); + /* + ** cancel the operation on the cursor, no additional OFETCH calls + ** will be issued for the existing cursor without an intervening + ** OEXEC call. + ** cursor - pointer to csrdef + */ + +sword ocisfe( struct csrdef *cursor, sword erropt, sword waitopt ); + /* + ** ocisfe - user interface set error options + ** set the error and cursor options. + ** allows user to set the options for dealing with fatal dml errors + ** and other cursor related options + ** see oerdef for valid settings + ** cursor - pointer to csrdef + ** erropt - error optionsn + ** waitopr - wait options + */ + + +/***************************************/ +/* COMMIT/ROLLBACK/AUTOCOMMIT */ +/***************************************/ +sword ocicom( ldadef *lda ); +sword ocirol( ldadef *lda ); + /* + ** ocicom - commit the current transaction + ** ocirol - roll back the current transaction + */ + +sword ocicon( ldadef *lda ); +sword ocicof( ldadef *lda ); + /* + ** ocicon - auto Commit ON + ** ocicof - auto Commit OFf + */ + + + +/************************/ +/* parsing */ +/************************/ +sword ocisq3(struct csrdef *cursor, oratext * /* sqlstm */, sword sqllen); + /* + ** ocisq3 - user interface parse sql statement + ** cursor - pointer to csrdef + ** sqlstm - pointer to SQL statement + ** sqllen - length of SQL statement. if -1, strlen(sqlstm) is used + */ + + + +/***************************/ +/* BINDING */ +/***************************/ +/* these are for the opcode in ocibndps, ocidfnps */ +#define OCI_PCWS 0 +#define OCI_SKIP 1 + +sword ocibin( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + oratext *fmt, sword fmtl, sword fmtt ); +sword ocibrv( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, sb2 *indp, + oratext *fmt, sword fmtl, sword fmtt ); +sword ocibra( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *aln, ub2 *rcp, ub4 mal, ub4 *cal, + oratext *fmt, sword fmtl, sword fmtt ); +sword ocibndps( struct csrdef *cursor, ub1 opcode, oratext *sqlvar, + sb4 sqlvl, ub1 *progv, sb4 progvl, sword ftype, + sword scale, sb2 *indp, ub2 *aln, ub2 *rcp, sb4 pv_skip, + sb4 ind_skip, sb4 len_skip, sb4 rc_skip, ub4 mal, + ub4 *cal, oratext *fmt, sb4 fmtl, sword fmtt ); +sword ocibnn ( struct csrdef *cursor, ub2 sqlvn, ub1 *progv, sword progvl, + sword ftype, sword scale, oratext *fmt, sword fmtl, + sword fmtt ); +sword ocibrn( struct csrdef *cursor, sword sqlvn, ub1 *progv, sword progvl, + sword ftype, sword scale, sb2 *indp, oratext *fmt, sword fmtl, + sword fmtt ); + /* + ** ocibin - bind by value by name + ** ocibrv - bind by reference by name + ** ocibra - bind by reference by name (array) + ** ocibndps - bind by reference by name (array) piecewise or with skips + ** ocibnn - bind by value numeric + ** ocibrn - bind by reference numeric + ** + ** the contents of storage specified in bind-by-value calls are + ** evaluated immediately. + ** the addresses of storage specified in bind-by-reference calls are + ** remembered, and the contents are examined at every execute. + ** + ** cursor - pointer to csrdef + ** sqlvn - the number represented by the name of the bind variables + ** for variables of the form :n or &n for n in [1..256) + ** (i.e. &1, :234). unnecessarily using larger numbers + ** in the range wastes space. + ** sqlvar - the name of the bind variable (:name or &name) + ** sqlval - the length of the name; + ** in bindif -1, strlen(bvname) is used + ** progv - pointer to the object to bind. + ** progvl - length of object to bind. + ** in bind-by-value if specified as -1 then strlen(bfa) is + ** used (really only makes sends with character types) + ** in bind-by-value, if specified as -1 then UB2MAXVAL + ** is used. Again this really makes sense only with + ** SQLT_STR. + ** ftype - datatype of object + ** indp - pointer to indicator variable. + ** -1 means to ignore bfa/bfl and bind NULL; + ** not -1 means to bind the contents of bfa/bfl + ** bind the contents pointed to by bfa + ** aln - Alternate length pointer + ** rcp - Return code pointer + ** mal - Maximum array length + ** cal - Current array length pointer + ** fmt - format string + ** fmtl - length of format string; if -1, strlen(fmt) is used + ** fmtt - desired output type after applying forat mask. Not + ** really yet implemented + ** scale - number of decimal digits in a cobol packed decimal (type 7) + ** + ** Note that the length of bfa when bound as SQLT_STR is reduced + ** to strlen(bfa). + ** Note that trailing blanks are stripped of storage of SQLT_STR. + */ + +/***************************/ +/* DESCRIBING */ +/***************************/ +sword ocidsc ( struct csrdef *cursor, sword pos, sb2 *dbsize, sb2 *fsize, + sb2 *rcode, sb2 *dtype, sb1 *buf, sb2 *bufl, sb2 *dsize ); +sword ocidsr( struct csrdef *cursor, sword pos, sb2 *dbsize, sb2 *dtype, + sb2 *fsize ); +sword ocinam( struct csrdef *cursor, sword pos, sb1 *tbuf, sb2 *tbufl, + sb1 *buf, sb2 *bufl ); + /* + ** ocidsc, ocidsr: Obtain information about a column + ** ocinam : get the name of a column + ** cursor - pointer to csrdef + ** pos - position in select list from [1..N] + ** dbsize - place to store the database size + ** fsize - place to store the fetched size + ** rcode - place to store the fetched column returned code + ** dtype - place to store the data type + ** buf - array to store the column name + ** bufl - place to store the column name length + ** dsize - maximum display size + ** tbuf - place to store the table name + ** tbufl - place to store the table name length + */ + +sword ocidsp ( struct csrdef *cursor, sword pos, sb4 *dbsize, sb2 *dbtype, + sb1 *cbuf, sb4 *cbufl, sb4 *dsize, sb2 *pre, sb2 *scl, + sb2 *nul ); + +sword ocidpr( ldadef *lda, oratext *object_name, size_t object_length, + void * reserved1, size_t reserved1_length, void * reserved2, + size_t reserved2_length, ub2 *overload, ub2 *position, + ub2 *level, oratext **argument_name, ub2 *argument_length, + ub2 *datatype, ub1 *default_supplied, ub1 *in_out, + ub4 *length, sb2 *precision, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *total_elements ); + /* + ** OCIDPR - User Program Interface: Describe Stored Procedure + ** + ** This routine is used to obtain information about the calling + ** arguments of a stored procedure. The client provides the + ** name of the procedure using "object_name" and "database_name" + ** (database name is optional). The client also supplies the + ** arrays for OCIDPR to return the values and indicates the + ** length of array via the "total_elements" parameter. Upon return + ** the number of elements used in the arrays is returned in the + ** "total_elements" parameter. If the array is too small then + ** an error will be returned and the contents of the return arrays + ** are invalid. + ** + ** + ** EXAMPLE : + ** + ** Client provides - + ** + ** object_name - SCOTT.ACCOUNT_UPDATE@BOSTON + ** total_elements - 100 + ** + ** + ** ACCOUNT_UPDATE is an overloaded function with specification : + ** + ** type number_table is table of number index by binary_integer; + ** table account (account_no number, person_id number, + ** balance number(7,2)) + ** table person (person_id number(4), person_nm varchar2(10)) + ** + ** function ACCOUNT_UPDATE (account number, + ** person person%rowtype, amounts number_table, + ** trans_date date) return accounts.balance%type; + ** + ** function ACCOUNT_UPDATE (account number, + ** person person%rowtype, amounts number_table, + ** trans_no number) return accounts.balance%type; + ** + ** + ** Values returned - + ** + ** overload position argument level datatype length prec scale rad + ** ------------------------------------------------------------------- + ** 0 0 0 NUMBER 22 7 2 10 + ** 0 1 ACCOUNT 0 NUMBER 22 0 0 0 + ** 0 2 PERSON 0 RECORD 0 0 0 0 + ** 0 2 PERSON_ID 1 NUMBER 22 4 0 10 + ** 0 2 PERSON_NM 1 VARCHAR2 10 0 0 0 + ** 0 3 AMOUNTS 0 TABLE 0 0 0 0 + ** 0 3 1 NUMBER 22 0 0 0 + ** 0 4 TRANS_NO 0 NUMBER 22 0 0 0 + ** + ** 1 0 0 NUMBER 22 7 2 10 + ** 1 1 ACCOUNT 0 NUMBER 22 0 0 0 + ** 1 2 PERSON 0 RECORD 0 0 0 0 + ** 1 2 PERSON_ID 1 NUMBER 22 4 0 10 + ** 1 2 PERSON_NM 1 VARCHAR2 10 0 0 0 + ** 1 3 AMOUNTS 0 TABLE 0 0 0 0 + ** 1 3 1 NUMBER 22 0 0 0 + ** 1 4 TRANS_DATE 0 NUMBER 22 0 0 0 + ** + ** + ** OCIDPR Argument Descriptions - + ** + ** ldadef - pointer to ldadef + ** object_name - object name, synonyms are also accepted and will + ** be translate, currently only procedure and function + ** names are accepted, also NLS names are accepted. + ** Currently, the accepted format of a name is + ** [[part1.]part2.]part3[@dblink] (required) + ** object_length - object name length (required) + ** reserved1 - reserved for future use + ** reserved1_length - reserved for future use + ** reserved2 - reserved for future use + ** reserved2_length - reserved for future use + ** overload - array indicating overloaded procedure # (returned) + ** position - array of argument positions, position 0 is a + ** function return argument (returned) + ** level - array of argument type levels, used to describe + ** sub-datatypes of data structures like records + ** and arrays (returned) + ** argument_name - array of argument names, only returns first + ** 30 characters of argument names, note storage + ** for 30 characters is allocated by client (returned) + ** argument_length - array of argument name lengths (returned) + ** datatype - array of oracle datatypes (returned) + ** default_supplied - array indicating parameter has default (returned) + ** 0 = no default, 1 = default supplied + ** in_out - array indicating if argument is IN or OUT (returned + ** 0 = IN param, 1 = OUT param, 2 = IN/OUT param + ** length - array of argument lengths (returned) + ** precision - array of precisions (if number type)(returned) + ** scale - array of scales (if number type)(returned) + ** radix - array of radix (if number type)(returned) + ** spare - array of spares. + ** total_elements - size of arrays supplied by client (required), + ** total number of elements filled (returned) + */ + +/*************************************/ +/* DEFINING */ +/*************************************/ +sword ocidfi( struct csrdef *cursor, sword pos, ub1 *buf, sword bufl, + sword ftype, sb2 *rc, sword scale ); +sword ocidfn( struct csrdef *cursor, sword pos, ub1 *buf, sword bufl, + sword ftype, sword scale, sb2 *indp, oratext *fmt, sword fmtl, + sword fmtt, ub2 *rl, ub2 *rc ); +sword ocidfnps( struct csrdef *cursor, ub1 opcode, sword pos, ub1 *buf, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, oratext *fmt, sb4 fmtl, + sword fmtt, ub2 *rl, ub2 *rc, + sb4 pv_skip, sb4 ind_skip, sb4 len_skip, + sb4 rc_skip ); + + + /* Define a user data buffer using upidfn + ** cursor - pointer to csrdef + ** pos - position of a field or exp in the select list of a query + ** bfa/bfl - address and length of client-supplied storage + to receive data + ** ftype - user datatype + ** scale - number of fractional digits for cobol packed decimals + ** indp - place to store the length of the returned value. If returned + ** value is: + ** negative, the field fetched was NULL + ** zero , the field fetched was same length or shorter than + ** the buffer provided + ** positive, the field fetched was truncated + ** fmt - format string + ** fmtl - length of format string, if -1 strlent(fmt) used + ** rl - place to store column length after each fetch + ** rc - place to store column error code after each fetch + ** fmtt - fomat type + */ + +/********************************/ +/* PIECE INFORMATION GET/SET */ +/********************************/ +sword ocigetpi( struct csrdef *cursor, ub1 *piecep, + void **ctxpp, ub4 *iterp, ub4 *indexp ); +sword ocisetpi( struct csrdef *cursor, ub1 piece, + void *bufp, ub4 *lenp ); + + +/********************************/ +/* EXECUTE */ +/********************************/ +sword ociexe( struct csrdef *cursor ); +sword ociexn( struct csrdef *cursor, sword iters, sword roff ); +sword ociefn( struct csrdef *cursor, ub4 nrows, sword can, sword exact ); + /* + ** ociexe - execute a cursor + ** ociexn - execute a cursosr N times + ** cursor - pointer to a csrdef + ** iters - number of times to execute cursor + ** roff - offset within the bind variable array at which to begin + ** operations. + */ + + +/*********************************/ +/* FETCHING */ +/*********************************/ +sword ocifet( struct csrdef *cursor ); +sword ocifen( struct csrdef *cursor, sword nrows ); + /* ocifet - fetch the next row + ** ocifen - fetch n rows + ** cursor - pointer to csrdef + ** nrows - number of rows to be fetched + */ + +sword ocilng( struct csrdef *cursor, sword posit, ub1 *bfa, sb4 bfl, + sword dty, ub4 *rln, sb4 off ); + +/*********************************/ +/* CONVERSION */ +/*********************************/ +sword ocic32( struct csrdef *cursor ); + /* + ** Convert selected version 3 return codes to the equivalent + ** version 2 code. + ** csrdef->csrrc is set to the converted code + ** csrdef->csrft is set to v2 oracle statment type + ** csrdef->csrrpc is set to the rows processed count + ** csrdef->csrpeo is set to error postion + ** + ** cursor - pointer to csrdef + */ + + +sword ocir32( struct csrdef *cursor, sword retcode ); + /* + ** Convert selected version 3 return codes to the equivalent version 2 + ** code. + ** + ** cursor - pointer to csrdef + ** retcode - place to store the return code + */ + + +void ociscn( sword **arglst, char *mask_addr, sword **newlst ); + /* + ** Convert call-by-ref to call-by-value: + ** takes an arg list and a mask address, determines which args need + ** conversion to a value, and creates a new list begging at the address + ** of newlst. + ** + ** arglst - list of arguments + ** mast_addr _ mask address determines args needing conversion + ** newlst - new list of args + */ + +sword ocistf ( sword typ, sword bufl, sword rdig, oratext *fmt, + struct csrdef *cursor, sword *err ); +/* Convert a packed decimal buffer length (bytes) and scale to a format +** string of the form mm.+/-nn, where mm is the number of packed +** decimal digits, and nn is the scaling factor. A positive scale name +** nn digits to the rights of the decimal; a negative scale means nn zeros +** should be supplied to the left of the decimal. +** bufl - length of the packed decimal buffer +** rdig - number of fractional digits +** fmt - pointer to a string holding the conversion format +** cursor - pointer to csrdef +** err - pointer to word storing error code +*/ + + +/******************************************/ +/* Non-blocking operations */ +/******************************************/ +sword ocinbs( ldadef *lda ); /* set a connection to non-blocking */ +sword ocinbt( ldadef *lda ); /* test if connection is non-blocking */ +sword ocinbc( ldadef *lda ); /* clear a connection to blocking */ +sword ocinlo( ldadef *lda, struct hstdef *hst, oratext *conn, + sword connl, oratext *uid, sword uidl, + oratext *psw, sword pswl, sword audit ); + /* logon in non-blocking fashion */ +/* ocinlo allows an application to logon in non-blocking fashion. +** lda - pointer to ldadef +** hst - pointer to a 256 byte area, must be cleared to zero before call +** conn - the database link (if specified @LINK in uid will be ignored) +** connl - length of conn; if -1 strlen(conn) is used +** uid - user id [USER[/PASSWORD][@LINK]] +** uidl - length of uid, if -1 strlen(uid) is used +** psw - password string; ignored if specified in uid +** pswl - length of psw, if -1 strlen(psw) is used +** audit - is not supported; the only permissible value is 0 +*/ + +/***************************************************/ +/* Procedure Declaration for Pro*C */ +/***************************************************/ +/* Note: The following routines are used in Pro*C and have the + same interface as their couterpart in OCI. + Althought the interface follows for more details please refer + to the above routines */ + +/******************************************/ +/* initialization/logon/logof */ +/******************************************/ +sword ocipin( ub4 mode ); + +sword ologin( ldadef *lda, sb2 areacount ); +sword ologon( ldadef *lda, sb2 areacount ); + +/*****************************************/ +/* Open/Close/Parse Cursor */ +/*****************************************/ + +/* +** ocisqd - oci delayed parse (Should be used only with deferred upi/oci) +** FUNCTION: Call upidpr to delay the parse of the sql statement till the +** time that a call needs to be made to the kernel (execution or +** describe time ) +** RETURNS: Oracle return code. +*/ +sword ocisq7( struct csrdef *cursor, oratext * /* sqlstm */, sb4 sqllen, + sword defflg, ub4 sqlt ); + +/*****************************************/ +/* Bind */ +/*****************************************/ +sword obind( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + oratext *fmt, sword fmtl, sword fmtt ); +sword obindn( struct csrdef *cursor, ub2 sqlvn, ub1 *progv, sword progvl, + sword ftype, sword scale, oratext *fmt, sword fmtl, + sword fmtt ); + +/**********************************************/ +/* Define */ +/**********************************************/ +sword odfinn( struct csrdef *cursor, sword pos, ub1 *buf, sword bufl, + sword ftype, sb2 *rc, sword scale ); + +/**********************************************/ +/* Describe */ +/**********************************************/ +sword odsrbn( struct csrdef *cursor, sword pos, sb2 *dbsize, sb2 *dtype, + sb2 *fsize ); + + +/******************************************/ +/* Non-blocking operations */ +/******************************************/ +sword onblon( ldadef *lda, struct hstdef *hst, oratext *conn, + sword connl, oratext *uid, sword uidl, + oratext *psw, sword pswl, sword audit ); + /* logon in non-blocking fashion */ +sword ocignfd( ldadef *lda, void *nfdp ); /* get native fd */ + +ub2 ocigft_getFcnType( ub2 oertyp ); /* get sql function code */ + +#endif diff --git a/OCI/include/ocidem.h b/OCI/include/ocidem.h new file mode 100644 index 0000000..f7bb786 --- /dev/null +++ b/OCI/include/ocidem.h @@ -0,0 +1,113 @@ +/* + * + */ + +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ocidem.h - OCI demo header + MODIFIED (MM/DD/YY) + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + whe 04/07/99 - bug#810071 + whe 03/19/99 - lrg 32079 etc.: putting static back for oci_func_tab + nmacnaug 02/02/99 - static declarations should not be in header files + mygopala 09/22/97 - Fix for bug 550351 + surman 03/14/97 - Merge 413362 to 8.0.3 + surman 11/08/96 - 413362: Add SS_64BIT_SERVER macro + emendez 04/07/94 - merge changes from branch 1.6.710.1 + emendez 02/02/94 - Fix for bug 157576 + jnlee 01/05/93 - include oratypes.h once, make oci_func_tab static + rkooi2 10/26/92 - More portability mods + rkooi2 10/22/92 - Change text back to char to avoid casts + rkooi2 10/20/92 - Changes to make it portable + sjain 03/16/92 - Creation +*/ + +/* + * ocidem.h + * + * Declares additional functions and data structures + * used in the OCI C sample programs. + */ + + +#ifndef ORATYPES +#include +#endif /* ORATYPES */ + +#ifndef OCIDFN +#include +#endif /* OCIDFN */ + +#ifndef OCIDEM +#define OCIDEM + + +/* internal/external datatype codes */ +#define VARCHAR2_TYPE 1 +#define NUMBER_TYPE 2 +#define INT_TYPE 3 +#define FLOAT_TYPE 4 +#define STRING_TYPE 5 +#define ROWID_TYPE 11 +#define DATE_TYPE 12 + +/* ORACLE error codes used in demonstration programs */ +#define VAR_NOT_IN_LIST 1007 +#ifndef NO_DATA_FOUND +# define NO_DATA_FOUND 1403 +#endif +#define NULL_VALUE_RETURNED 1405 + +/* some SQL and OCI function codes */ +#define FT_INSERT 3 +#define FT_SELECT 4 +#define FT_UPDATE 5 +#define FT_DELETE 9 + +#define FC_OOPEN 14 + +/* + * OCI function code labels, + * corresponding to the fc numbers + * in the cursor data area. + */ +static const text *oci_func_tab[] = {(text *) "not used", +/* 1-2 */ (text *) "not used", (text *) "OSQL", +/* 3-4 */ (text *) "not used", (text *) "OEXEC, OEXN", +/* 5-6 */ (text *) "not used", (text *) "OBIND", +/* 7-8 */ (text *) "not used", (text *) "ODEFIN", +/* 9-10 */ (text *) "not used", (text *) "ODSRBN", +/* 11-12 */ (text *) "not used", (text *) "OFETCH, OFEN", +/* 13-14 */ (text *) "not used", (text *) "OOPEN", +/* 15-16 */ (text *) "not used", (text *) "OCLOSE", +/* 17-18 */ (text *) "not used", (text *) "not used", +/* 19-20 */ (text *) "not used", (text *) "not used", +/* 21-22 */ (text *) "not used", (text *) "ODSC", +/* 23-24 */ (text *) "not used", (text *) "ONAME", +/* 25-26 */ (text *) "not used", (text *) "OSQL3", +/* 27-28 */ (text *) "not used", (text *) "OBNDRV", +/* 29-30 */ (text *) "not used", (text *) "OBNDRN", +/* 31-32 */ (text *) "not used", (text *) "not used", +/* 33-34 */ (text *) "not used", (text *) "OOPT", +/* 35-36 */ (text *) "not used", (text *) "not used", +/* 37-38 */ (text *) "not used", (text *) "not used", +/* 39-40 */ (text *) "not used", (text *) "not used", +/* 41-42 */ (text *) "not used", (text *) "not used", +/* 43-44 */ (text *) "not used", (text *) "not used", +/* 45-46 */ (text *) "not used", (text *) "not used", +/* 47-48 */ (text *) "not used", (text *) "not used", +/* 49-50 */ (text *) "not used", (text *) "not used", +/* 51-52 */ (text *) "not used", (text *) "OCAN", +/* 53-54 */ (text *) "not used", (text *) "OPARSE", +/* 55-56 */ (text *) "not used", (text *) "OEXFET", +/* 57-58 */ (text *) "not used", (text *) "OFLNG", +/* 59-60 */ (text *) "not used", (text *) "ODESCR", +/* 61-62 */ (text *) "not used", (text *) "OBNDRA", +/* 63-64 */ (text *) "OBINDPS", (text *) "ODEFINPS", +/* 65-66 */ (text *) "OGETPI", (text *) "OSETPI" +}; + +#endif /* OCIDEM */ + diff --git a/OCI/include/ocidfn.h b/OCI/include/ocidfn.h new file mode 100644 index 0000000..873c5a7 --- /dev/null +++ b/OCI/include/ocidfn.h @@ -0,0 +1,249 @@ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ocidfn.h - OCI Definations + NOTES + Shipped to users. + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 11/25/02 - change binary float/double codes + srseshad 11/14/02 - Add SQLT_IBFLOAT, SQLT_IBDOUBLE + mxyang 09/17/02 - grabtrans 'mmorsi_obj_float' + srseshad 09/06/02 - Add binary float/double + aahluwal 06/04/02 - bug 2360115 + kmuthukk 05/02/00 - add SQLT_PNTY + amangal 07/30/99 - Merge into 8.1.6 : Bug 879031 + tnbui 07/28/99 - Remove SQLT_TIMESTAMP_ITZ + tnbui 07/21/99 - SQLT_TIMESTAMP_LTZ + tnbui 06/16/99 - TIMESTAMP WITH IMPLICIT TIME ZONE + whe 04/07/99 - bug#810075 + whe 03/19/99 - lrg 32079 etc.: move HDA def from ocidem.h to ocidfn. + skmishra 05/10/98 - + vyanaman 04/16/98 - update sql92 datatypes + khnguyen 01/16/98 - + khnguyen 12/23/97 - SQLT* for datetimes and intervals + tanguyen 08/19/97 - + dchatter 03/18/97 - porting exception 390897 + dchatter 05/02/97 - merge porting exception + dalpern 12/04/96 - SQLCS_LIT_NULL added + cxcheng 11/14/96 - add SQLT_BFILE/SQLT_CFILE to fix compile prob + cxcheng 11/12/96 - add SQLT_NCO for named collection + lchidamb 10/17/96 - add SQLT_VST and SQLT_ODT + sgollapu 10/14/96 - Mutual exclusion of ocidfn and sqldef + sgollapu 10/07/96 - OCI Simplification + aroy 09/09/96 - add SQLCS* definitions + slari 08/07/96 - add SQLT_RDD, rowid descriptor + slari 06/12/96 - remove SQLT_TTBL + dchatter 04/21/96 - prepare for merge into main + slari 08/24/95 - b299432, define CDA_SIZE + zwalcott 02/28/96 - add SQLT_BFILEE and SQLT_CFILEE. + lchidamb 02/22/96 - make dtys consistent with dtydef.h + lchidamb 02/16/96 - add SQLT_BFILEE and SQLT_CFILEE + lchidamb 01/30/96 - rename new datatypes for v8 + lchidamb 09/06/95 - add new datatypes + slari 05/11/95 - add OCI_EV_DEF and OCI_EV_TSF + dchatter 04/06/95 - add ifdef flags around OCI_flags + dchatter 03/08/95 - piece values + dchatter 03/06/95 - merge changes from branch 1.2.720.3 + jfbrown 02/17/95 - merge changes from branch 1.2.720.2 + dchatter 02/08/95 - olog call modes + jfbrown 02/03/95 - remove non-printable characters + lchidamb 12/06/94 - merge changes from branch 1.2.720.1 + lchidamb 10/04/94 - added field chk to cda_head, cda_def + dchatter 07/05/94 - SQLT_CUR added + rkooi2 11/27/92 - Changing e* datatypes to s* + rkooi2 10/26/92 - More portability mods + rkooi2 10/22/92 - Added #ifndef ORATYPES ... + rkooi2 10/18/92 - Changes to make it portable. + sjain 03/16/92 - Creation +*/ + +/* + * ocidfn.h + * + * Common header file for OCI C sample programs. + * This header declares the cursor and logon data area structure. + * The types used are defined in . + * + */ + +#ifndef OCIDFN +#define OCIDFN + +#include + +/* The cda_head struct is strictly PRIVATE. It is used + internally only. Do not use this struct in OCI programs. */ + +struct cda_head { + sb2 v2_rc; + ub2 ft; + ub4 rpc; + ub2 peo; + ub1 fc; + ub1 rcs1; + ub2 rc; + ub1 wrn; + ub1 rcs2; + sword rcs3; + struct { + struct { + ub4 rcs4; + ub2 rcs5; + ub1 rcs6; + } rd; + ub4 rcs7; + ub2 rcs8; + } rid; + sword ose; + ub1 chk; + void *rcsp; +}; + +/* +** Size of HDA area: +** 512 for 64 bit arquitectures +** 256 for 32 bit arquitectures +*/ + +#if defined(SS_64BIT_SERVER) || defined(__64BIT__) +# define HDA_SIZE 512 +#else +# define HDA_SIZE 256 +#endif + +#if defined(SS_64BIT_SERVER) || defined(__64BIT__) +#define CDA_SIZE 88 +#else +# define CDA_SIZE 64 +#endif + +/* the real CDA, padded to CDA_SIZE bytes in size */ +struct cda_def { + sb2 v2_rc; /* V2 return code */ + ub2 ft; /* SQL function type */ + ub4 rpc; /* rows processed count */ + ub2 peo; /* parse error offset */ + ub1 fc; /* OCI function code */ + ub1 rcs1; /* filler area */ + ub2 rc; /* V7 return code */ + ub1 wrn; /* warning flags */ + ub1 rcs2; /* reserved */ + sword rcs3; /* reserved */ + struct { /* rowid structure */ + struct { + ub4 rcs4; + ub2 rcs5; + ub1 rcs6; + } rd; + ub4 rcs7; + ub2 rcs8; + } rid; + sword ose; /* OSD dependent error */ + ub1 chk; + void *rcsp; /* pointer to reserved area */ + ub1 rcs9[CDA_SIZE - sizeof (struct cda_head)]; /* filler */ +}; + +typedef struct cda_def Cda_Def; + +/* the logon data area (LDA) + is the same shape as the CDA */ +typedef struct cda_def Lda_Def; + +/* OCI Environment Modes for opinit call */ +#define OCI_EV_DEF 0 /* default single-threaded environment */ +#define OCI_EV_TSF 1 /* thread-safe environment */ + +/* OCI Logon Modes for olog call */ +#define OCI_LM_DEF 0 /* default login */ +#define OCI_LM_NBL 1 /* non-blocking logon */ + +/* + * since sqllib uses both ocidef and ocidfn the following defines + * need to be guarded + */ +#ifndef OCI_FLAGS +#define OCI_FLAGS + +/* OCI_*_PIECE defines the piece types that are returned or set +*/ +#define OCI_ONE_PIECE 0 /* there or this is the only piece */ +#define OCI_FIRST_PIECE 1 /* the first of many pieces */ +#define OCI_NEXT_PIECE 2 /* the next of many pieces */ +#define OCI_LAST_PIECE 3 /* the last piece of this column */ +#endif + +#ifndef SQLDEF + +/* input data types */ +#define SQLT_CHR 1 /* (ORANET TYPE) character string */ +#define SQLT_NUM 2 /* (ORANET TYPE) oracle numeric */ +#define SQLT_INT 3 /* (ORANET TYPE) integer */ +#define SQLT_FLT 4 /* (ORANET TYPE) Floating point number */ +#define SQLT_STR 5 /* zero terminated string */ +#define SQLT_VNU 6 /* NUM with preceding length byte */ +#define SQLT_PDN 7 /* (ORANET TYPE) Packed Decimal Numeric */ +#define SQLT_LNG 8 /* long */ +#define SQLT_VCS 9 /* Variable character string */ +#define SQLT_NON 10 /* Null/empty PCC Descriptor entry */ +#define SQLT_RID 11 /* rowid */ +#define SQLT_DAT 12 /* date in oracle format */ +#define SQLT_VBI 15 /* binary in VCS format */ +#define SQLT_BFLOAT 21 /* Native Binary float*/ +#define SQLT_BDOUBLE 22 /* NAtive binary double */ +#define SQLT_BIN 23 /* binary data(DTYBIN) */ +#define SQLT_LBI 24 /* long binary */ +#define SQLT_UIN 68 /* unsigned integer */ +#define SQLT_SLS 91 /* Display sign leading separate */ +#define SQLT_LVC 94 /* Longer longs (char) */ +#define SQLT_LVB 95 /* Longer long binary */ +#define SQLT_AFC 96 /* Ansi fixed char */ +#define SQLT_AVC 97 /* Ansi Var char */ +#define SQLT_IBFLOAT 100 /* binary float canonical */ +#define SQLT_IBDOUBLE 101 /* binary double canonical */ +#define SQLT_CUR 102 /* cursor type */ +#define SQLT_RDD 104 /* rowid descriptor */ +#define SQLT_LAB 105 /* label type */ +#define SQLT_OSL 106 /* oslabel type */ + +#define SQLT_NTY 108 /* named object type */ +#define SQLT_REF 110 /* ref type */ +#define SQLT_CLOB 112 /* character lob */ +#define SQLT_BLOB 113 /* binary lob */ +#define SQLT_BFILEE 114 /* binary file lob */ +#define SQLT_CFILEE 115 /* character file lob */ +#define SQLT_RSET 116 /* result set type */ +#define SQLT_NCO 122 /* named collection type (varray or nested table) */ +#define SQLT_VST 155 /* OCIString type */ +#define SQLT_ODT 156 /* OCIDate type */ + +/* datetimes and intervals */ +#define SQLT_DATE 184 /* ANSI Date */ +#define SQLT_TIME 185 /* TIME */ +#define SQLT_TIME_TZ 186 /* TIME WITH TIME ZONE */ +#define SQLT_TIMESTAMP 187 /* TIMESTAMP */ +#define SQLT_TIMESTAMP_TZ 188 /* TIMESTAMP WITH TIME ZONE */ +#define SQLT_INTERVAL_YM 189 /* INTERVAL YEAR TO MONTH */ +#define SQLT_INTERVAL_DS 190 /* INTERVAL DAY TO SECOND */ +#define SQLT_TIMESTAMP_LTZ 232 /* TIMESTAMP WITH LOCAL TZ */ + +#define SQLT_PNTY 241 /* pl/sql representation of named types */ + +/* cxcheng: this has been added for backward compatibility - + it needs to be here because ocidfn.h can get included ahead of sqldef.h */ +#define SQLT_FILE SQLT_BFILEE /* binary file lob */ +#define SQLT_CFILE SQLT_CFILEE +#define SQLT_BFILE SQLT_BFILEE + +/* CHAR/NCHAR/VARCHAR2/NVARCHAR2/CLOB/NCLOB char set "form" information */ +#define SQLCS_IMPLICIT 1 /* for CHAR, VARCHAR2, CLOB w/o a specified set */ +#define SQLCS_NCHAR 2 /* for NCHAR, NCHAR VARYING, NCLOB */ +#define SQLCS_EXPLICIT 3 /* for CHAR, etc, with "CHARACTER SET ..." syntax */ +#define SQLCS_FLEXIBLE 4 /* for PL/SQL "flexible" parameters */ +#define SQLCS_LIT_NULL 5 /* for typecheck of NULL and empty_clob() lits */ + +#endif /* SQLDEF */ +#endif /* OCIDFN */ diff --git a/OCI/include/ociextp.h b/OCI/include/ociextp.h new file mode 100644 index 0000000..7026a68 --- /dev/null +++ b/OCI/include/ociextp.h @@ -0,0 +1,282 @@ +/* + * + */ + +/* Copyright (c) 1996, 2005, Oracle. All rights reserved. */ + +/* + NAME + ociextp.h - Interface Definitions for PL/SQL External Procedures + + DESCRIPTION + This header file contains C language callable interface from + PL/SQL External Procedures. + + PUBLIC FUNCTION(S) + OCIExtProcAllocCallMemory - Allocate Call memory + OCIExtProcRaiseExcp - Raise Exception + OCIExtProcRaiseExcpWithMsg - Raise Exception with message + OCIExtProcGetEnv - Get OCI Environment + + PRIVATE FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + rdecker 01/10/02 - change 32k to MAX_OEN for error numbers + sagrawal 07/20/01 - Statement Handle to safe cal outs + abrumm 04/19/01 - move include of oci.h after defines/typedef + rdecker 02/22/01 - lint fix + bpalaval 02/08/01 - Change text to oratext. + sagrawal 06/16/00 - ref cursor in callouts + whe 09/01/99 - 976457:check __cplusplus for C++ code + asethi 04/15/99 - Created (by moving ociextp.h from /vobs/plsql/public) + rhari 03/25/97 - Use ifndef + rhari 12/18/96 - Include oratypes.h + rhari 12/11/96 - #416977, Flip values of return codes + rhari 12/02/96 - Define Return Code Macros + rhari 11/18/96 - Error number is int + rhari 10/30/96 - Fix OCIExtProcRaiseExcpWithMsg + rhari 10/30/96 - Get rid of warnings + rhari 10/04/96 - Fix OCIExtProcRaiseExcpWithMsg + rhari 09/23/96 - Creation + +*/ + + +#ifndef OCIEXTP_ORACLE +# define OCIEXTP_ORACLE + +# ifndef ORATYPES +# include +# endif + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/* ----------------------------- Return Codes ----------------------------- */ +/* Success and Error return codes for certain external procedure interface + * functions. If a particular interface function returns OCIEXTPROC_SUCCESS + * or OCIEXTPROC_ERROR, then applications must use these macros to check + * for return values. + * + * OCIEXTPROC_SUCCESS -- External Procedure Success Return Code + * OCIEXTPROC_ERROR -- External Procedure Failure Return Code + */ +#define OCIEXTPROC_SUCCESS 0 +#define OCIEXTPROC_ERROR 1 + + +/* --------------------------- With-Context Type --------------------------- */ +/* + * The C callable interface to PL/SQL External Procedures require the + * With-Context parameter to be passed. The type of this structure is + * OCIExtProcContext is is opaque to the user. + * + * The user can declare the With-Context parameter in the application as + * + * OCIExtProcContext *with_context; + */ +typedef struct OCIExtProcContext OCIExtProcContext; + +/* NOTE: OCIExtProcContext must be visible prior to including */ + +# ifndef OCI_ORACLE +# include +# endif + + +/* ----------------------- OCIExtProcAllocCallMemory ----------------------- */ +/* OCIExtProcAllocCallMemory + * Allocate N bytes of memory for the duration of the External Procedure. + * + * Memory thus allocated will be freed by PL/SQL upon return from the + * External Procedure. You must not use any kind of 'free' function on + * memory allocated by OCIExtProcAllocCallMemory. + * Use this function to allocate memory for function returns. + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * Type of with_context : OCIExtProcContext * + * amount - The number of bytes to allocate. + * Type of amount : size_t + * + * Output : + * Nothing + * + * Return : + * An untyped (opaque) Pointer to the allocated memory. + * + * Errors : + * A 0 return value should be treated as an error + * + * EXAMPLE + * text *ptr = (text *)OCIExtProcAllocCallMemory(wctx, 1024) + * + */ +#define OCIExtProcAllocCallMemory(with_context, amount) \ +ociepacm(with_context, (size_t)amount) + + + + +/* -------------------------- OCIExtProcRaiseExcp -------------------------- */ +/* OCIExtProcRaiseExcp + * Raise an Exception to PL/SQL. + * + * Calling this function signalls an exception back to PL/SQL. After a + * successful return from this function, the External Procedure must start + * its exit handling and return back to PL/SQL. Once an exception is + * signalled to PL/SQL, INOUT and OUT arguments, if any, are not processed + * at all. + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * Type of with_context : OCIExtProcContext * + * errnum - Oracle Error number to signal to PL/SQL. errnum + * must be a positive number and in the range 1 to MAX_OEN + * Type of errnum : int + * Output : + * Nothing + * + * Return : + * OCIEXTPROC_SUCCESS - If the call was successful. + * OCIEXTPROC_ERROR - If the call failed. + * + */ +#define OCIExtProcRaiseExcp(with_context, errnum) \ +ocieperr(with_context, (int)errnum) + + + + + +/* ---------------------- OCIExtProcRaiseExcpWithMsg ---------------------- */ +/* OCIExtProcRaiseExcpWithMsg + * Raise an exception to PL/SQL. In addition, substitute the + * following error message string within the standard Oracle error + * message string. See note for OCIExtProcRaiseExcp + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * Type of with_context : OCIExtProcContext * + * errnum - Oracle Error number to signal to PL/SQL. errnum + * must be a positive number and in the range 1 to MAX_OEN + * Type of errnum : int + * errmsg - The error message associated with the errnum. + * Type of errmsg : char * + * len - The length of the error message. 0 if errmsg is + * null terminated string. + * Type of len : size_t + * Output : + * Nothing + * + * Return : + * OCIEXTPROC_SUCCESS - If the call was successful. + * OCIEXTPROC_ERROR - If the call failed. + * + */ +#define OCIExtProcRaiseExcpWithMsg(with_context, errnum, errmsg, msglen) \ +ociepmsg(with_context, (int)errnum, errmsg, (size_t)msglen) + + + +/* --------------------------- OCIExtProcGetEnv --------------------------- */ +/* OCIExtProcGetEnv + * Get OCI Environment + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * + * Output : + * envh - The OCI Environment handle. + * svch - The OCI Service handle. + * errh - The OCI Error handle. + * + * Return : + * OCI_SUCCESS - Successful completion of the function. + * OCI_ERROR - Error. + * + */ +#define OCIExtProcGetEnv(with_context, envh, svch, errh) \ +ociepgoe(with_context, envh, svch, errh) + + + +/* ------------------------ OCIInitializeStatementHandle ------------------- */ +/* OCIreateStatementHandle + * Initialize Statement Handle + * + * PARAMETERS + * Input : + * wctx - The + * cursorno - The cursor number for which we need to initialize + * the statement handle + * svch - The OCI Service handle. + * + * Output : + * stmthp - The OCI Statement handle. + * errh - The OCI Error handle. + * + * Return : + * OCI_SUCCESS - Successful completion of the function. + * OCI_ERROR - Error. + * + */ +#define OCIInitializeStatementHandle(wctx, cursorno, svch, stmthp, errh) \ +ociepish(wctx, cursor, svch, stmthp, errh) + + + + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + + +void *ociepacm(OCIExtProcContext *with_context, size_t amount); + + + +size_t ocieperr(OCIExtProcContext *with_context, int error_number); + + + +size_t ociepmsg(OCIExtProcContext *with_context, int error_number, + oratext *error_message, size_t len ); + + + +sword ociepgoe(OCIExtProcContext *with_context, OCIEnv **envh, + OCISvcCtx **svch, OCIError **errh); + + +#endif /* OCIEXTP_ORACLE */ diff --git a/OCI/include/ocikpr.h b/OCI/include/ocikpr.h new file mode 100644 index 0000000..425d696 --- /dev/null +++ b/OCI/include/ocikpr.h @@ -0,0 +1,165 @@ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ocikpr.h - header of K & R compilers + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + porangas 12/04/00 - Forward merge bug#974710 to 9i + sgollapu 05/19/98 - Change text to OraText + dchatter 04/21/96 - + dchatter 11/10/95 - add ognfd() - get native fd + lchidamb 04/06/95 - drop maxdsz from obindps/odefinps + slari 04/07/95 - add opinit + dchatter 03/08/95 - osetpi and ogetpi + lchidamb 12/09/94 - add obindps() and odefinps() + dchatter 03/06/95 - merge changes from branch 1.1.720.2 + dchatter 11/14/94 - merge changes from branch 1.1.720.1 + dchatter 02/08/95 - olog call; drop onblon + dchatter 10/31/94 - new functions for non-blocking oci + rkooi2 11/27/92 - Changing datatypes (in comments) and return types + rkooi2 10/26/92 - More portability mods + rkooi2 10/18/92 - Changed to agree with oci.c + sjain 03/16/92 - Creation +*/ + +/* + * Declare the OCI functions. + * Prototype information is commented out. + * Use this header for non-ANSI C compilers. + * Note that you will need to include ocidfn.h in the .c files + * to get the definition for cda_def. + */ + +#ifndef OCIKPR +#define OCIKPR + +#include + +/* + * Oci BIND (Piecewise or with Skips) + */ +sword obindps( struct cda_def *cursor, ub1 opcode, OraText *sqlvar, + sb4 sqlvl, ub1 *pvctx, sb4 progvl, + sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip, + ub4 maxsiz, ub4 *cursiz, + OraText *fmt, sb4 fmtl, sword fmtt ); +sword obreak( struct cda_def *lda ); +sword ocan ( struct cda_def *cursor ); +sword oclose( struct cda_def *cursor ); +sword ocof ( struct cda_def *lda ); +sword ocom ( struct cda_def *lda ); +sword ocon ( struct cda_def *lda ); + + +/* + * Oci DEFINe (Piecewise or with Skips) + */ +sword odefinps( struct cda_def *cursor, ub1 opcode, sword pos,ub1 *bufctx, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sb4 fmtl, sword fmtt, + ub2 *rlen, ub2 *rcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip ); +sword odescr( struct cda_def *cursor, sword pos, sb4 *dbsize, + sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize, + sb2 *prec, sb2 *scale, sb2 *nullok ); +sword odessp( struct cda_def *cursor, OraText *objnam, size_t onlen, + ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t rsv2ln, + ub2 *ovrld, ub2 *pos, ub2 *level, OraText **argnam, + ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* mode, + ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *arrsiz ); +sword oerhms( struct cda_def *lda, sb2 rcode, OraText *buf, + sword bufsiz ); +sword oermsg( sb2 rcode, OraText *buf ); +sword oexec ( struct cda_def *cursor ); +sword oexfet( struct cda_def *cursor, ub4 nrows, + sword cancel, sword exact ); +sword oexn ( struct cda_def *cursor, sword iters, sword rowoff ); +sword ofen ( struct cda_def *cursor, sword nrows ); +sword ofetch( struct cda_def *cursor ); +sword oflng ( struct cda_def *cursor, sword pos, ub1 *buf, + sb4 bufl, sword dtype, ub4 *retl, sb4 offset ); +sword ogetpi( struct cda_def *cursor, ub1 *piecep, void **ctxpp, + ub4 *iterp, ub4 *indexp ); +sword opinit( ub4 mode ); +sword olog ( struct cda_def *lda, ub1 *hst, + OraText *uid, sword uidl, + OraText *psw, sword pswl, + OraText *conn, sword connl, + ub4 mode ); +sword ologof( struct cda_def *lda ); +sword oopen ( struct cda_def *cursor, struct cda_def *lda, + OraText *dbn, sword dbnl, sword arsize, + OraText *uid, sword uidl ); +sword oopt ( struct cda_def *cursor, sword rbopt, sword waitopt ); +sword oparse( struct cda_def *cursor, OraText *sqlstm, sb4 sqllen, + sword defflg, ub4 lngflg ); +sword orol ( struct cda_def *lda ); +sword osetpi( struct cda_def *cursor, ub1 piece, void *bufp, + ub4 *lenp ); +void sqlld2 ( struct cda_def *lda, OraText *cname, sb4 *cnlen ); +void sqllda ( struct cda_def *lda ); + +/* non-blocking functions */ +sword onbset( struct cda_def *lda ); +sword onbtst( struct cda_def *lda ); +sword onbclr( struct cda_def *lda ); +sword ognfd ( struct cda_def *lda, void *fdp ); + + + +/* + * OBSOLETE FUNCTIONS + */ + +/* + * OBSOLETE BIND CALLS-- use obindps() + */ +sword obndra( struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz, + ub4 *cursiz, OraText *fmt, sword fmtl, sword fmtt ); +sword obndrn( struct cda_def *cursor, sword sqlvn, ub1 *progv, + sword progvl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt ); +sword obndrv( struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sword fmtl, sword fmtt ); + +/* + * OBSOLETE DEFINE CALLS-- use odefinps() + */ +sword odefin( struct cda_def *cursor, sword pos, ub1 *buf, + sword bufl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt, ub2 *rlen, + ub2 *rcode ); + + +/* older calls ; preferred equivalent calls above */ +sword odsc ( struct cda_def *cursor, sword pos, sb2 *dbsize, + sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf, + sb2 *bufl, sb2 *dsize ); +sword oname ( struct cda_def *cursor, sword pos, sb1 *tbuf, + sb2 *tbufl, sb1 *buf, sb2 *bufl ); +sword olon ( struct cda_def *lda, OraText *uid, sword uidl, + OraText *pswd, sword pswdl, sword audit ); +sword orlon ( struct cda_def *lda, ub1 *hda, OraText *uid, + sword uidl, OraText *pswd, sword pswdl, sword audit ); +sword osql3 ( struct cda_def *cda, OraText *sqlstm, sword sqllen ); + + + + + + + +#endif /* OCIKPR */ + + + + + + + diff --git a/OCI/include/ocilib.h b/OCI/include/ocilib.h new file mode 100644 index 0000000..6275f54 --- /dev/null +++ b/OCI/include/ocilib.h @@ -0,0 +1,98 @@ +/*===================================================================================================================== + Copyright(c) 2012 ORIGIN. + Unpublished - All rights reserved +======================================================================================================================= +File description: + + Filename: ocilib.h + Module : OCI + + This Header file of OCI library Package. + +======================================================================================================================= +Date Name Description of Change +1-Feb-2015 Ray Initialize creation +$HISTORY$ +=====================================================================================================================*/ +#include +#include +#include +#include +#include +//#include + +#define OCI_FAIL 1 +#define OCI_OK 0 + +#ifdef __cplusplus +extern "C" +{ +#endif + /** + * ݿ. + * @param username - û + * @param password - + * @param dbname - ݿSID + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ConnServer(char* username, char* password, char* dbname); + + + /** + * ִSQL. + * @param SQL - SQL + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ExecuteSQLNoInputParam(char* SQL); + + /** + * ִSQL. + * @param SQL - SQL + * @param inputValueCount - + * @param inputValue - ֵ + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int ExecuteSQL(char* SQL, int inputValueCount, char** inputValue); + + /** + * IJѯSQL. + * @param SQL - SQL + * @param outputColumn - е + * @param outputValueCount - е + * @param outputValue - + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int QuerySQLNoInputParam(char* SQL, int* outputColumn, int* outputValueCount, char**** outputValue); + + /** + * IJѯSQL. + * @param SQL - SQL + * @param inputValueCount - + * @param inputValue - ֵ + * @param outputColumn - е + * @param outputValueCount - е + * @param outputValue - + * @return - OCI_OK or error code + * + * ORACLE ݿװ + */ + extern int QuerySQL(char* SQL, int inputValueCount, char** inputValue, int* outputColumn, int* outputValueCount, char**** outputValue); + + /** + * Ͽݿ. + * + * ORACLE ݿװ + */ + extern void DisConnServer(); + +#ifdef __cplusplus +} +#endif diff --git a/OCI/include/ocixml.h b/OCI/include/ocixml.h new file mode 100644 index 0000000..1c30188 --- /dev/null +++ b/OCI/include/ocixml.h @@ -0,0 +1,188 @@ +/* Copyright (c) 2003, 2009, Oracle and/or its affiliates. +All rights reserved. */ + +/* + NAME + ocixml.h - OCIXMLType functions + + DESCRIPTION + This file contains all OCIXMLType functions defined in ocixml.c + + + ****************************IMPORTANT*********************************** + *** If you change the signatures of any fucntions in this file, make sure + *** to make same changes to Windows OSD file ociclnt.c. Otherwise, users + *** of OCI instant client like ODP.NET will have build issues or crashes + ****************************IMPORTANT*********************************** + + PUBLIC FUNCTION(S) + OCIXMLTypeNew() + OCIXMLTypeCreateFromSrc() + OCIXMLTypeCreateFromSrcWithSchema() + OCIXMLTypeTransform() + OCIXMLTypeExtract() + OCIXMLTypeIsSchemaBased() + OCIXMLTypeValidate() + OCIXMLTypeExists() + OCIXMLTypeGetDOM() + OCIXMLTypeGetFromDOM() + OCIDOMFree() + OCIXMLSEMutexAcq() + OCIXMLSEMutexRel() + OCIXMLUpdateNodeValues() + + INTERNAL FUNCTION(S) + + EXAMPLES + + NOTES + + MODIFIED (MM/DD/YY) + spetride 03/02/09 - add isdoc to OCIXMLTypeCreateFromSrc* + bsthanik 01/17/07 - 5753599: wrappers for service mutex acq/rel + bkhaladk 05/10/06 - add setpicklepref + nitgupta 01/30/06 - add signatures for OCIBinXMl* + dmukhin 06/16/05 - ANSI prototypes; miscellaneous cleanup + dmukhin 06/14/05 - ANSI prototypes; miscellaneous cleanup + ataracha 12/04/03 - convert public oci api to ansi + ataracha 01/21/03 - ataracha_uni_capi_cleanup + ataracha 01/08/03 - Creation + +*/ +#ifndef OCI_ORACLE +# include +#endif + +#ifndef XML0_ORACLE +# include +#endif + +#ifndef OCIXML_ORACLE +# define OCIXML_ORACLE + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* parameters for OCIXMLUpdateNodeValues */ +struct OCIXMLunv +{ + void * xpth_OCIXMLunv; /* xpath expression */ + void * val_OCIXMLunv; /* value - string literal or xmltype */ + ub4 xpthL_OCIXMLunv; /* length of xpath expression string */ + ub4 valL_OCIXMLunv; /* length of value string */ + ub1 tp_OCIXMLunv; /* type of value - xmltype of string */ + +#define OCIXMLUNV_XTP 0x00 /* param is xmltype */ +#define OCIXMLUNV_STP 0x01 /* param is string literal */ +#define OCIXMLUNV_STM 0x02 /* param is a stream (kghsstream *) */ +#define OCIXMLUNV_CLOB 0x03 /* param is a CLOB locator (kolblc *) */ +#define OCIXMLUNV_BLOB 0x04 /* param is a BLOB locator (kolblc *) */ +}; +typedef struct OCIXMLunv OCIXMLunv; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ +sword OCIXMLTypeNew(OCISvcCtx *svchp, OCIError *errhp, OCIDuration dur, + OraText *elname, ub4 elname_Len, + OraText *schemaURL, ub4 schemaURL_Len, + OCIXMLType **retInstance); + +sword OCIXMLTypeCreateFromSrc(OCISvcCtx *svchp, OCIError *errhp, + OCIDuration dur, ub1 src_type, void *src_ptr, + sb4 ind, OCIXMLType **retInstance, ub4 csid); +sword OCIXMLTypeCreateFromSrcInt(OCISvcCtx *svchp, OCIError *errhp, + OCIDuration dur, ub1 src_type, void *src_ptr, + sb4 ind, OCIXMLType **retInstance, ub4 csid, + boolean isdoc); + +sword OCIXMLTypeCreateFromSrcWithSchema(OCISvcCtx *svchp, OCIError *errhp, + OCIDuration dur, ub1 src_type, void *src_ptr, + sb4 ind, OraText *schemaURL, ub4 schemaURL_Len, + boolean wellformed, boolean valid, + OCIXMLType **retInstance, ub4 csid); +sword OCIXMLTypeCreateFromSrcWithSchemaInt(OCISvcCtx *svchp, OCIError *errhp, + OCIDuration dur, ub1 src_type, void *src_ptr, + sb4 ind, OraText *schemaURL, ub4 schemaURL_Len, + boolean wellformed, boolean valid, + OCIXMLType **retInstance, ub4 csid, + boolean isdoc); + +sword OCIXMLTypeExtract(OCIError *errhp, + OCIXMLType *doc, OCIDuration dur, + OraText *xpathexpr, ub4 xpathexpr_Len, + OraText *nsmap, ub4 nsmap_Len, + OCIXMLType **retDoc); + +sword OCIXMLTypeTransform(OCIError *errhp, OCIDuration dur, + OCIXMLType *doc, OCIXMLType *xsldoc, + OCIXMLType **retDoc); + +/* Note: xpathexpr is case sensitive */ +sword OCIXMLTypeExists(OCIError *errhp, OCIXMLType *doc, + OraText *xpathexpr, ub4 xpathexpr_Len, + OraText *nsmap, ub4 nsmap_Len, + boolean *retval); + +sword OCIXMLTypeIsSchemaBased(OCIError *errhp, + OCIXMLType *doc, boolean *retval); + +sword OCIXMLTypeIsFragment(OCIError *errhp, OCIXMLType *doc, boolean *retval); + +sword OCIXMLTypeGetSchema(OCIError *errhp, OCIXMLType *doc, + OCIXMLType **schemadoc, + OraText **schemaURL, ub4 *schemaURL_Len, + OraText **rootelem, ub4 *rootelem_Len); + +sword OCIXMLTypeValidate(OCIError *errhp, OCIXMLType *doc, + OraText *schemaURL, ub4 schemaURL_Len, boolean *retval); + +sword OCIXMLTypeGetDOM(OCIError *errhp, OCIXMLType *doc, OCIDuration dur, + OCIDOMDocument **retDom); + +sword OCIXMLTypeGetFromDOM(OCIError *errhp, OCIDOMDocument *domdoc, + OCIXMLType **retXMLType); + +sword OCIXMLTypeGetNS(OCIError *errhp, OCIXMLType *domdoc, + OraText **ns, ub4 *ns_len); + +sword OCIDOMFree(OCIError *errhp, OCIDOMDocument *domdoc); + +sword OCIBinXmlCreateReposCtxFromConn(OCIEnv *env, OCISvcCtx *svcctx, + OCIError *err, OCIBinXmlReposCtx **ctx); +sword OCIBinXmlCreateReposCtxFromCPool(OCIEnv *env, OCICPool *cpool, + OCIError *err, OCIBinXmlReposCtx **ctx); +sword OCIBinXmlSetReposCtxForConn(OCISvcCtx *dataconn, + OCIBinXmlReposCtx *reposctx); + +#define OCIXML_FORMATTYPE_TEXT 0 +#define OCIXML_FORMATTYPE_BINXML 1 + +sword OCIBinXmlSetFormatPref(xmldocnode *doc, ub4 format); + +/* OCI Wrapper to acquire mutex associated with service handle and + * env handle + */ +sword OCIXMLSEMutexAcq(OCISvcCtx *svchp, OCIError *errhp); + +/* release wrapper corresponding to OCIXMLSEMutexAcq */ +sword OCIXMLSEMutexRel(OCISvcCtx *svchp, OCIError *errhp); + +/* acquires OCI svc and env mutexes, updates values of nodes pointed to by + * given XPATH locations, and releases mutexes. + */ +sword OCIXMLUpdateNodeValues(OCISvcCtx *svchp, OCIError *errhp, OCIXMLType + **docp, struct OCIXMLunv *values, ub4 numvalues, oratext *nsmap, + ub4 nsmapl); +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCIXML_ORACLE */ diff --git a/OCI/include/ocixmldb.h b/OCI/include/ocixmldb.h new file mode 100644 index 0000000..95ece13 --- /dev/null +++ b/OCI/include/ocixmldb.h @@ -0,0 +1,141 @@ +/* Copyright (c) 2003, 2009, Oracle and/or its affiliates. +All rights reserved. */ + +/* + NAME + ocixmldb.h - XDB public functions + + DESCRIPTION + This file contains XDB specific public functions required for DOM C-API. + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + struct xmlctx *OCIXmlDbInitXmlCtx(OCIEnv *, OCISvcCtx *, OCIError *, + ocixmldbparam *params, int num_params); + + void OCIXmlDbFreeXmlCtx(struct xmlctx *xctx); + + + ------------------------------------------------------------------------ + EXAMPLES + + NOTES + + MODIFIED (MM/DD/YY) + ataracha 12/11/03 - remove redundant definitions + ataracha 05/28/03 - change names + ataracha 02/18/03 - add oratypes, remove XMLERR_* + imacky 02/01/03 - remove xml.h; xdbs fix + ataracha 01/24/03 - use "struct xmlctx" instead of xmlctx + imacky 01/28/03 - fix XMLERR defs + ataracha 01/21/03 - ataracha_uni_capi_cleanup + ataracha 01/09/03 - Creation + +*/ + +#ifndef ORATYPES +#include +#endif + +#ifndef OCI_ORACLE +# include +#endif + +#ifndef OCIXMLDB_ORACLE +# define OCIXMLDB_ORACLE + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +#ifndef XMLCTX_DEFINED +# define XMLCTX_DEFINED +/* DATATYPE xmlctx - XML top-level context +*/ +struct xmlctx; typedef struct xmlctx xmlctx; +#endif + +typedef enum +{ + XCTXINIT_OCIDUR = 1, + XCTXINIT_ERRHDL = 2 +} ocixmldbpname; + +typedef struct ocixmldbparam +{ + ocixmldbpname name_ocixmldbparam; + void *value_ocixmldbparam; +} ocixmldbparam; + +#define NUM_OCIXMLDBPARAMS 2 + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ +/***************************************************************************** + DESCRIPTION + +-----------------------------OCIXmlDbInitXmlCtx--------------------------------- +Name +OCIXmlDbInitXmlCtx +Purpose +To get a xmlctx structure initialized with error-handler and XDB callbacks. +Syntax +struct xmlctx *OCIXmlDbInitXmlCtx (OCIEnv *envhp, + OCISvcCtx *svchp, + OCIError *err, + params_ocixmldb *params, + int num_params); +Parameters +envhp (IN) - The OCI environment handle +svchp (IN) - The OCI service handle +errhp (IN) - The OCI error handle +params (IN)- This contains the following optional parameters : + (a) OCIDuration dur (IN - The OCI Duration (Default: OCI_DURATION_SESSION) + (b) void (*err_handler) (sword, (const oratext *) (IN) - + Pointer to the error handling function (Default: null) +num_params (IN) - Number of parameters to be read from parameter params. + If the value of num_params exceeds the size of array + "params", unexpected behavior will result. + +Returns +A pointer to xmlctx structure, with xdb context, error handler and callbacks +populated with appropriate values. This is later used for all API calls. NULL +if no database connection available. + +-----------------------------OCIXmlDbFreeXmlCtx---------------------------- +Name +OCIXmlDbFreeXmlCtx +Pupose +To free any allocations done during OCIXmlDbInitXmlCtx. +Syntax +void OCIXmlDbFreeXmlCtx (struct xmlctx *xctx) +Parameters +xctx (IN) - The xmlctx to terminate +Returns +- +******************************************************************************/ + +struct xmlctx *OCIXmlDbInitXmlCtx(OCIEnv *, OCISvcCtx *, OCIError *, + ocixmldbparam *, int); + +void OCIXmlDbFreeXmlCtx(struct xmlctx *xctx); +sword OCIXmlDbStreamFromXMLType(OCIError *errhp, void **stream, + OCIXMLType *doc, ub4 mode); +sword OCIXmlDbStreamRead(OCIError *errhp, void *stream, + void *bufp, sb8 *len, ub4 mode); +sword OCIXmlDbStreamClose(OCIError *errhp, void *stream); +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCIXMLDB_ORACLE */ diff --git a/OCI/include/ocixstream.h b/OCI/include/ocixstream.h new file mode 100644 index 0000000..fc9a641 --- /dev/null +++ b/OCI/include/ocixstream.h @@ -0,0 +1,1899 @@ +/* Copyright (c) 2006, 2009, Oracle and/or its affiliates. +All rights reserved. */ + +/* + NAME + ocixstreams.h - OCI X-Stream APIs + + DESCRIPTION + OCI APIs for X-Stream + + RELATED DOCUMENTS + + EXPORT FUNCTION(S) + + INTERNAL FUNCTION(S) + + EXAMPLES + + NOTES + + MODIFIED (MM/DD/YY) + thoang 05/08/09 - Add OCILCR_NEW_ONLY_MODE + praghuna 05/11/09 - removed 'TODO' comments + thoang 02/15/09 - Change lob_column_* to chunk_column_* + thoang 01/27/09 - 8216105 - add OLD/NEW column parms to OCILCRHeaderGet + rihuang 01/05/09 - Add OCI_LCR_ATTR_TRACKING_LABEL + tianli 11/28/08 - add DDL flags + tianli 11/20/08 - add OCILCRAttribute methods + thoang 11/20/08 - Define OCI_LCR_MAX_TXID_LEN + tianli 11/07/08 - add edition + thoang 11/10/08 - change return type to sword for consistency + thoang 10/16/08 - remove commit position arg + tianli 08/26/08 - rename client_name in XStreamIn attach call + thoang 06/30/08 - Support XStream APIs using two callbacks. + praghuna 05/14/08 - charset id is ub2, OCILcrGetRowStmtWithBindVar + thoang 06/02/08 - Define reserved attach mode for internal clients + elu 05/08/08 - add pos functions + thoang 04/29/08 - API changes + jinwu 04/28/08 - add OCILcrGetExtraAttributes + elu 04/14/08 - add OCI_LCR_MAX_POSITION_LEN + juyuan 03/27/08 - add flag for Set/GetHeader and Set/GetColumnInfo + thoang 02/25/08 - Add GetNextChunk and SetNextChunk + rihuang 03/24/08 - Signature change for OCILcrNew + elu 03/05/08 - add lcr id + praghuna 02/26/08 - Added OCILcrGetRowStmt + thoang 01/25/08 - Add wm_time parameter to XApply APIs + thoang 12/28/07 - Add mode parameter to XApplyDetach + thoang 11/07/07 - Change extapp apis to return ub1[] watermark + juyuan 05/23/07 - XStream In + thoang 11/13/06 - Add XStream Out methods + thoang 11/13/06 - Add LCR getter methods + nshodhan 05/12/06 - streams OCI APIs + nshodhan 05/12/06 - Creation + +*/ + +#ifndef OCIXSTREAM_ORACLE +# define OCIXSTREAM_ORACLE + +#ifndef ORATYPES +# include +#endif + +#ifndef OCI_ORACLE +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ +/* LCR Types -- must match with values defined in kngo.h */ +#define OCI_LCR_XROW (3) /* External Row LCR */ +#define OCI_LCR_XDDL (4) /* External DDL LCR */ + +/* DML Command Types -- must match with values defined in kngl.h */ +#define OCI_LCR_ROW_CMD_INSERT "INSERT" +#define OCI_LCR_ROW_CMD_DELETE "DELETE" +#define OCI_LCR_ROW_CMD_UPDATE "UPDATE" +#define OCI_LCR_ROW_CMD_COMMIT "COMMIT" +#define OCI_LCR_ROW_CMD_LOB_WRITE "LOB WRITE" +#define OCI_LCR_ROW_CMD_LOB_TRIM "LOB TRIM" +#define OCI_LCR_ROW_CMD_LOB_ERASE "LOB ERASE" + +/* LCR Extra Attribute Name -- must match with values defined in knll.h */ +#define OCI_LCR_ATTR_THREAD_NO "THREAD#" +#define OCI_LCR_ATTR_ROW_ID "ROW_ID" +#define OCI_LCR_ATTR_SESSION_NO "SESSION#" +#define OCI_LCR_ATTR_SERIAL_NO "SERIAL#" +#define OCI_LCR_ATTR_USERNAME "USERNAME" +#define OCI_LCR_ATTR_TX_NAME "TX_NAME" + +/* below are non first class LCR field specific */ +#define OCI_LCR_ATTR_EDITION_NAME "EDITION_NAME" +#define OCI_LCR_ATTR_MESSAGE_TRACKING_LABEL "MESSAGE_TRACKING_LABEL" + +/* the maximum total number of attributes, total of extra attributes + * plus non first class LCR field. */ +#define OCI_LCR_MAX_ATTRIBUTES 8 + +/* Row LCR column value types used in OCILCRRowColumnInfoGet/Set functions. */ +#define OCI_LCR_ROW_COLVAL_OLD 0 /* OLD columns */ +#define OCI_LCR_ROW_COLVAL_NEW 1 /* NEW columns */ + +/* maximum length for position */ +#define OCI_LCR_MAX_POSITION_LEN 64 + +/* maximum length for txid */ +#define OCI_LCR_MAX_TXID_LEN 128 + +/* Valid column flags used in OCILCRRowColumnInfoSet, OCILCRRowColumnInfoGet, + * OCILCRLobInfoSet, OCILCRLobInfoGet, OCIXStreamOutChunkReceive, + * OCIXStreamInChunkSend calls. + */ +#define OCI_LCR_COLUMN_LOB_DATA (0x00000001) /* col contains lob data */ +#define OCI_LCR_COLUMN_LONG_DATA (0x00000002) /* col contains long data*/ +#define OCI_LCR_COLUMN_EMPTY_LOB (0x00000004) /* col has an empty lob */ +#define OCI_LCR_COLUMN_LAST_CHUNK (0x00000008) /* last chunk of current col*/ +#define OCI_LCR_COLUMN_AL16UTF16 (0x00000010) /* col is in AL16UTF16 fmt */ +#define OCI_LCR_COLUMN_NCLOB (0x00000020) /* col has NCLOB data */ +#define OCI_LCR_COLUMN_XML_DATA (0x00000040) /* col contains xml data */ +#define OCI_LCR_COLUMN_XML_DIFF (0x00000080)/* col contains xmldiff data */ +#define OCI_LCR_COLUMN_ENCRYPTED (0x00000100) /* col is encrypted */ + +/* OCI_LCR_COLUMN_UPDATED is set only for the modified columns in the NEW + * column list of an update LCR. + */ +#define OCI_LCR_COLUMN_UPDATED (0x00000200) /* col is updated */ + +/* Valid bit values for flag parameter in the following APIs: + * - OCIXStreamOutChunkReceive & OCIXStreamOutLCRReceive + * - OCIXStreamInChunkSend & OCIXStreamInLCRSend + */ +#define OCI_XSTREAM_MORE_ROW_DATA (0x00000001) /* LCR contains more data */ + +/* Valid mode flag for OCILCRHeaderGet and OCILCRRowColumnInfoGet functions */ +#define OCILCR_NEW_ONLY_MODE (0x0001) /* NEW columns only -- dont */ + /* include OLD columns */ + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ +/* +------------------------------------------------------------------------------= +NAME + OCILCRNew - OCI LCR NEW +DESCRIPTION + Create a new Streams LCR for the user specified duration and type +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + duration (IN) - allocation duration for LCR memory + lcrtype (IN) - LCR type (OCI_LCR_XROW / OCI_LCR_XDDL) + lcrp (IN/OUT) - Streams LCR. (*lcrp must be initialized to null.) + mode (IN) - mode +NOTES + - memory will be based on the duration specified by the user + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRNew(OCISvcCtx *svchp, + OCIError *errhp, + OCIDuration duration, + ub1 lcrtype, + void **lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRFree - OCI LCR FREE +DESCRIPTION + Free Streams LCR specified by the user +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + lcrp (IN/OUT) - Streams LCR + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRFree(OCISvcCtx *svchp, + OCIError *errhp, + void *lcrp, + ub4 mode); + + +/* +------------------------------------------------------------------------------= +NAME + OCILCRHeaderSet - OCI LCR Set Header +DESCRIPTION + Initialize elements of Streams LCR's header +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + src_db_name (IN) - Pointer to Canonicalized source database name. + Must be non-NULL. + src_db_name_len (IN) - Length of source database name in bytes + excluding NULL terminator. Should follow Oracle + naming conventions and size limitations. + cmd_type (IN) - For ROW LCRs: OCI_LCR_ROW_CMD_XXXXXXX + For DDL LCRs: One of the command types + corresponding to OCI Reference manual + cmd_type_len (IN) - Length of cmd_type. + owner (IN) - Canonicalized table owner name. Not required + for COMMIT LCR. + owner_len (IN) - Length of owner name in bytes excluding the + NULL terminator. Should follow Oracle naming + conventions and size limitations. + oname (IN) - Canonicalized table name. Not required for + COMIT LCR. + oname_len (IN) - Length of table name in bytes excluding the + NULL terminator. Should follow Oracle naming + conventions and size limitations. + tag (IN) - A binary tag that enables tracking of the LCR. + For example, this tag can be used to determine + the original source database of the DML + statement if apply forwarding is used. + tag_len (IN) - Number of bytes in the tag. Cannot exceed 2000 + bytes + txid (IN) - Transaction ID. + txid_len (IN) - Length of transaction id in bytes excluding the + NULL terminator. Should not exceeed + OCI_LCR_MAX_TXID_LEN bytes. + src_time (IN) - The time when the change was generated at the + source database. + position (IN) - position for LCR. Must be byte-comparable. + position_len (IN) - Length of position. Must be non-zero. + flag (IN) - LCR flag. + lcrp (IN/OUT) - Streams LCR + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode + - This function clears the current contents of the input LCR before + setting the header to the new values. +------------------------------------------------------------------------------= +*/ +sword OCILCRHeaderSet(OCISvcCtx *svchp, + OCIError *errhp, + oratext *src_db_name, + ub2 src_db_name_len, + oratext *cmd_type, + ub2 cmd_type_len, + oratext *owner, + ub2 owner_len, + oratext *oname, + ub2 oname_len, + ub1 *tag, + ub2 tag_len, + oratext *txid, + ub2 txid_len, + OCIDate *src_time, + ub1 *position, + ub2 position_len, + oraub8 flag, + void *lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRHeaderGet - OCI LCR Get Header +DESCRIPTION + Get header information from Streams LCR +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + src_db_name (OUT) - Pointer to Canonicalized source database name. + Optional, if src_db_name is specified then + must specify src_db_name_len as well. + src_db_name_len (OUT) - Length of source database name in bytes + excluding NULL terminator. + Optional, if specified src_db_name_len then + must specify src_db_name as well. + cmd_type (OUT) - Command type. Must be non-null if + cmd_type_len is non-null. Must be null if + cmd_type_len is NULL. + cmd_type_len (OUT) - Length of cmd_type. Optional. + owner (OUT) - Canonicalized table owner name. + Optional, if owner is specified then + must specify owner_len as well. + owner_len (OUT) - Length of owner name in bytes excluding the + NULL terminator. + Optional, if owner_len is specified then + must specify owner as well. + oname (OUT) - Canonicalized table name. + Optional, if oname is specified then + must specify oname_len as well. + oname_len (OUT) - Length of table name in bytes excluding the + NULL terminator. + Optional, if oname_len is specified then + must specify oname as well. + tag (OUT) - A binary tag that enables tracking of the LCR. + For example, this tag can be used to determine + the original source database of the + DML statement if apply forwarding is used. + Optional, if tag is specified then + must specify tag_len as well. + tag_len (OUT) - Number of bytes in the tag. + Optional, if tag_len is specified then + must specify tag as well. + txid (OUT) - Transaction ID. + Optional, if txid is specified then + must specify txid_len as well. + txid_len (OUT) - Length of transaction id in bytes excluding + the NULL terminator. + Optional, if txid_len is specified then + must specify txid as well. + src_time (OUT) - The time when the change was generated at the + source database. Optional. + old_columns (OUT) - Number of columns in the OLD column list. + Return 0 if input lcr is DDL LCR. Optional. + new_columns (OUT) - Number of columns present in either + the OLD or NEW column list. + Return 0 if input lcr is DDL LCR. Optional. + See NOTES below for the special mode supported + by this function. + position (OUT) - LCR position. Optional. + position_len (OUT) - Length of position. Must be non-null if + position is non-null. Must be null if + position is null. + flag (OUT) - LCR flag. Optional. + lcrp (IN) - Streams LCR + mode (IN) - mode (see NOTES) +NOTES + - Parameter src_time is optional. If specified the appropriate return + structure must be pre-allocated before calling OCILCRHeaderGet. + - The return values for src_db_name, cmd_type, owner, oname, tag, txid and + position are shallow-copied (i.e., they point directly into the LCR + structure). + - Valid mode flags: + - OCILCR_NEW_ONLY_MODE: if this mode is specified then the new_columns + returned is the count of the columns in the NEW column list only. + Otherwise, the new_columns returned is the number of distinct + columns present in either the NEW or the OLD column list of the given + ROW LCR. +------------------------------------------------------------------------------= +*/ + +sword OCILCRHeaderGet(OCISvcCtx *svchp, + OCIError *errhp, + oratext **src_db_name, + ub2 *src_db_name_len, + oratext **cmd_type, + ub2 *cmd_type_len, + oratext **owner, + ub2 *owner_len, + oratext **oname, + ub2 *oname_len, + ub1 **tag, + ub2 *tag_len, + oratext **txid, + ub2 *txid_len, + OCIDate *src_time, + ub2 *old_columns, + ub2 *new_columns, + ub1 **position, + ub2 *position_len, + oraub8 *flag, + void *lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRRowColumnInfoSet - OCI LCR ROW SET COLUMN INFO +DESCRIPTION + Populates column information as specified by the user. +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + column_value_type (IN) - ROW LCR column value type: + - OCI_LCR_ROW_COLVAL_OLD + - OCI_LCR_ROW_COLVAL_NEW + num_columns (IN) - Number of columns to be populated + column_names (IN) - Pointer to an array of column names. Column + names must be canonicalized. Column names should + follow Oracle naming conventions + column_name_lens (IN) - Pointer to an array of column name lengths + in bytes, excluding the NULL terminator. + column_dtyp (IN) - Pointer to an array of column datatypes. + column_valuesp (IN) - Pointer to an array of column data values. + column_indp (IN) - Pointer to an indicator array. For all datatypes, + this is a pointer to an array of OCIInd values + (OCI_IND_NULL/OCI_IND_NOTNULL). + column_alensp (IN) - Pointer to an array of actual column lengths in + bytes. + column_csetfp (IN) - Pointer to an array of character set forms for + the columns. The default form is SQLCS_IMPLICIT. + Setting this attribute will cause the database or + national character set to be used on the client + side. Set this attribute to SQLCS_NCHAR for the + national character set or SQLCS_IMPLICIT for the + database character set. + Pass 0 for non-character columns. + column_flags (IN) - Pointer to an array of column flags. + Possible bit values are OCI_LCR_COLUMN_* flags + listed above. + column_csid (IN) - Pointer to an array of column character set id. + The character set id is only required for + XMLType column; otherwise, the csid is ignored. + row_lcrp (IN/OUT)- Streams Row LCR pointer + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRRowColumnInfoSet(OCISvcCtx *svchp, + OCIError *errhp, + ub2 column_value_type, + ub2 num_columns, + oratext **column_names, + ub2 *column_name_lens, + ub2 *column_dtyp, + void **column_valuesp, + OCIInd *column_indp, + ub2 *column_alensp, + ub1 *column_csetfp, + oraub8 *column_flags, + ub2 *column_csid, + void *row_lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRRowColumnInfoGet - OCI LCR ROW GET COLUMN INFO +DESCRIPTION + Returns column information as requested by the user. +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + column_value_type (IN) - ROW LCR column value type: + - OCI_LCR_ROW_COLVAL_OLD + - OCI_LCR_ROW_COLVAL_NEW + (See NOTES for special mode supported by this + function.) + num_columns (OUT) - Number of columns in requested column list + column_names (IN/OUT)- Pointer to an array of column names. + Optional. If specified then column_namesl must + be specified as well, and both arrays must be the + size specified by array_size parameter. + column_name_lens (IN/OUT)- Pointer to an array of column name lengths + in bytes, excluding the NULL terminator. + Optional. If specified then column_names must + be specified as well, and both arrays must be the + size specified by array_size parameter. + column_dtyp (IN/OUT)- Pointer to an array of column datatypes. + Optional. If specified then this array must be + the size specified by array_size parameter. + column_valuesp (IN/OUT)- Pointer to an array of column data values. + Optional. If specified then this array must be + the size specified by array_size parameter. + column_indp (IN/OUT)- Pointer to an indicator array. For all datatypes, + this is a pointer to an array of OCIInd values + (OCI_IND_NULL/OCI_IND_NOTNULL). + Optional. If specified then this array must be + the size specified by array_size parameter. + column_alensp (IN/OUT)- Pointer to an array of actual column lengths in + bytes. + Optional. If specified then this array must be + the size specified by array_size parameter. + column_csetfp (IN/OUT)- Pointer to an array of character set forms for + the columns. + Optional. If specified then this array must be + the size specified by array_size parameter. + column_flags (IN/OUT)- Pointer to an array of column flags for + the columns. + Optional. If specified then this array must be + the size specified by array_size parameter. + Possible bit values are OCI_LCR_COLUMN_* flags + listed above. + column_csid (IN/OUT)- Pointer to an array of column character set id for + the columns. + Optional. If specified then this array must be + the size specified by array_size parameter. + The column csid is returned only for XMLType + column. + row_lcrp (IN) - Streams Row LCR pointer + array_size (IN) - Size of each of above arrays + mode (IN) - mode (see NOTES) +NOTES + - For now, specify OCI_DEFAULT for mode + - If array_size is not large enough to accommodate the number of columns + in the requested column list then OCI_ERROR is returned. Parameter + num_columns will have the number of columns in the requested column list. + - The return values for column_names and column_valuesp will be shallow + copied (i.e., they reference directly into the LCR structure). + Client should not modify those pointers directly. + - Valid mode flags: + - OCILCR_NEW_ONLY_MODE: this mode is valid only for OCI_LCR_ROW_COLVAL_NEW + column_value_type; otherwise, an error is raised. + If this mode is specified then the columns returned include only the + columns in the NEW column list. + If this mode is not specified then the columns returned is the union + of the NEW columns plus the OLD columns that are not present in the + NEW column list. +------------------------------------------------------------------------------= +*/ +sword OCILCRRowColumnInfoGet(OCISvcCtx *svchp, + OCIError *errhp, + ub2 column_value_type, + ub2 *num_columns, + oratext **column_names, + ub2 *column_name_lens, + ub2 *column_dtyp, + void **column_valuesp, + OCIInd *column_indp, + ub2 *column_alensp, + ub1 *column_csetfp, + oraub8 *column_flags, + ub2 *column_csid, + void *row_lcrp, + ub2 array_size, + ub4 mode); + + +/* +------------------------------------------------------------------------------= +NAME + OCILCRDDLInfoSet - OCI LCR SET DDL INFO +DESCRIPTION + populates DDL information as sepcified by the user. +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + object_type (IN) - The type of object on which the DDL statement was + executed. The following are valid object types: + CLUSTER, FUNCTION, INDEX, LINK, OUTLINE, + PACKAGE, PACKAGE BODY, PROCEDURE, SEQUENCE, + SYNONYM, TABLE, TRIGGER, TYPE, USER, VIEW + LINK represents a database link. + NULL is also a valid object type. Specify NULL + for all object types not listed. + object_type_len (IN) - Length of object_type without the NULL terminator. + ddl_text (IN) - The text of the DDL statement. This parameter + should be set to a non-NULL value. + DDL text must be in Oracle DDL format. + ddl_text_len (IN) - DDL text length in bytes without NULL terminator. + logon_user (IN) - Canonicalized name of the user whose session + executed the DDL statement. Should follow Oracle + naming conventions and size limitations. + logon_user_len (IN) - logon user name length in bytes without NULL + terminator. + current_schema (IN) - The canonicalized schema name that is used if no + schema is specified explicitly for the modified + database objects in ddl_text. If a schema is + specified in ddl_text that differs from the one + specified for current_schema, then the schema + specified in ddl_text will be used. + This parameter should be set to a non-NULL value. + Should follow Oracle naming conventions and size + limitations. + current_schema_len (IN) - schema name length in bytes without NULL terminator + base_table_owner (IN) - If the DDL statement is a table related DDL + (such as CREATE TABLE and ALTER TABLE), or if the + DDL statement involves a table (such as creating + a trigger on a table), then base_table_owner + specifies the canonicalized owner of the table + involved. Otherwise, base_table_owner is NULL. + Should follow Oracle naming conventions and size + limitations. + base_table_owner_len (IN)- base table owner name length in bytes without NULL + terminator. + base_table_name (IN) - If the DDL statement is a table related DDL (such + as CREATE TABLE and ALTER TABLE), or if the DDL + statement involves a table (such as creating a + trigger on a table), then base_table_name + specifies the canonicalized name of the table + involved. Otherwise, base_table_name is NULL. + Length of the above string without the NULL + terminator. Should follow Oracle naming + conventions and size limitations. + Should follow Oracle naming conventions and size + limitations. + base_table_name_len (IN)- base table name length in bytes without NULL + terminator. + flag (IN) - DDL LCR flag. + ddl_lcrp (IN/OUT) - Streams Ddl LCR pointer + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRDDLInfoSet(OCISvcCtx *svchp, + OCIError *errhp, + oratext *object_type, + ub2 object_type_len, + oratext *ddl_text, + ub4 ddl_text_len, + oratext *logon_user, + ub2 logon_user_len, + oratext *current_schema, + ub2 current_schema_len, + oratext *base_table_owner, + ub2 base_table_owner_len, + oratext *base_table_name, + ub2 base_table_name_len, + oraub8 flag, + void *ddl_lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRDDLInfoGet - OCI LCR GET DDL INFO +DESCRIPTION + Returns DDL information from specified lcr. +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + object_type (OUT) - The type of object on which the DDL statement + was executed. + Optional, if object_type is specified then + must specify object_type_len as well. + object_type_len (OUT) - Length of object_type without the NULL + terminator. + ddl_text (OUT) - The text of the DDL statement. + Optional, if ddl_text is specified then + must specify ddl_text_len as well. + ddl_text_len (OUT) - DDL text length in bytes without NULL + terminator. + logon_user (OUT) - Canonicalized name of the user whose session + executed the DDL statement. + Optional, if logon_user is specified then + must specify logon_user_len as well. + logon_user_len (OUT) - logon user name length in bytes without NULL + terminator. + current_schema (OUT) - The canonicalized schema name that is used if + no schema is specified explicitly for the + modified database objects in ddl_text. + Optional, if current_schema is specified then + must specify current_schema_len as well. + current_schema_len (OUT)- schema name length in bytes without NULL + terminator + base_table_owner (OUT) - If the DDL statement is a table related DDL + (such as CREATE TABLE and ALTER TABLE), or if + the DDL statement involves a table (such as + creating a trigger on a table), then + base_table_owner specifies the canonicalized + owner of the table involved. Otherwise, + base_table_owner is NULL. Optional, if + base_table_owner is specified then must specify + base_table_owner_len as well. + base_table_owner_len (OUT) - base table owner name length in bytes without + NULL terminator. + base_table_name (OUT) - If the DDL statement is a table related DDL + (such as CREATE TABLE and ALTER TABLE), or if + the DDL statement involves a table (such as + creating a trigger on a table), then + base_table_name specifies the canonicalized name + of the table involved. Otherwise, + base_table_name is NULL. Optional, if + base_table_name is specified then must specify + base_table_name_len as well. + base_table_name_len (OUT) - base table name length in bytes without NULL + terminator. + flag (OUT) - DDL LCR flag. Optional, data not returned if + NULL. + ddl_lcrp (IN) - Streams DDL LCR pointer + mode (IN) - mode (for future extention - not used currently) +RETURNS + OCI_SUCCESS or OCI_ERROR. +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRDDLInfoGet(OCISvcCtx *svchp, + OCIError *errhp, + oratext **object_type, + ub2 *object_type_len, + oratext **ddl_text, + ub4 *ddl_text_len, + oratext **logon_user, + ub2 *logon_user_len, + oratext **current_schema, + ub2 *current_schema_len, + oratext **base_table_owner, + ub2 *base_table_owner_len, + oratext **base_table_name, + ub2 *base_table_name_len, + oraub8 *flag, + void *ddl_lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRAttributesSet - OCI LCR SET ATTRIBUTES +DESCRIPTION + populates extra attribute information in ROW/DDL LCR, as well as any + non first class attributes that can not be set through + OCILCRHeaderSet, OCILCRDDLInfoSet, or OCILCRRowColumnInfoSet. + e.g. edition name +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + num_attrs (IN) - Number of extra attributes to be populated + attr_names (IN) - Pointer to an array of attribute names. Attribute + names must be canonicalized and should follow + Oracle naming conventions + attr_names_lens (IN) - Pointer to an array of attribute name lengths + in bytes, excluding the NULL terminator. + attr_dtyp (IN) - Pointer to an array of attribute datatypes. + attr_valuesp (IN) - Pointer to an array of attribute data values. + attr_indp (IN) - Pointer to an indicator array. For all datatypes, + this is a pointer to an array of OCIInd values + (OCI_IND_NULL/OCI_IND_NOTNULL). + attr_alensp (IN) - Pointer to an array of actual attribute lengths in + bytes. + lcrp (IN/OUT)- Streams (Row/DDL) LCR pointer + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRAttributesSet(OCISvcCtx *svchp, + OCIError *errhp, + ub2 num_attrs, + oratext **attr_names, + ub2 *attr_name_lens, + ub2 *attr_dtyp, + void **attr_valuesp, + OCIInd *attr_indp, + ub2 *attr_alensp, + void *lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRAttributesGet - OCI LCR GET EXTRA ATTRIBUTES +DESCRIPTION + Gets extra attribute information in (ROW/DDL) LCR, as well as any + non first class attributes that are not populated through + OCILCRHeaderGet, OCILCRDDLInfoGet, or OCILCRRowColumnInfoGet + e.g. edition name +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + num_attrs (OUT) - Number of extra attributes to be populated + attr_names (IN/OUT)- Pointer to an array of attribute names. Attribute + names must be canonicalized and should follow + Oracle naming conventions + attr_namesl (IN/OUT)- Pointer to an array of attribute name lengths + in bytes, excluding the NULL terminator. + attr_dtyp (IN/OUT)- Pointer to an array of attribute datatypes. + attr_valuesp (IN/OUT)- Pointer to an array of attribute data values. + attr_indp (IN/OUT)- Pointer to an indicator array. For all datatypes, + this is a pointer to an array of OCIInd values + (OCI_IND_NULL/OCI_IND_NOTNULL). + attr_alensp (IN/OUT)- Pointer to an array of actual attribute lengths in + bytes. + lcrp (IN) - Streams (Row/DDL) LCR pointer + array_size (IN) - Size of each of above arrays, use at least the size + defined by OCI_LCR_MAX_ATTRIBUTES + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode + - If array_size is not large enough to accommodate the number of attributes + in the requested attribute list then OCI_ERROR is returned. Parameter + num_attrs will return the suggested size. +------------------------------------------------------------------------------= +*/ +sword OCILCRAttributesGet(OCISvcCtx *svchp, + OCIError *errhp, + ub2 *num_attrs, + oratext **attr_names, + ub2 *attr_namesl, + ub2 *attr_dtyp, + void **attr_valuesp, + OCIInd *attr_indp, + ub2 *attr_alensp, + void *lcrp, + ub2 array_size, + ub4 mode); + +/*--------------------- OCILCRWhereClauseGet ----------------------------*/ +/* + NAME + OCILCRWhereClauseGet - OCI Get Where Clause + DESCRIPTION + Gets the Where clause statement for the given ROW LCR. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + wc_stmt (OUT) - Sql Statement equivalent to the + LCR has applied + wc_stmt_len (IN/OUT) - length of wc_stmt buffer + row_lcrp (IN) - row LCR to be converted to SQL + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + - For now, specify OCI_DEFAULT for mode + - WHERE clause generated for INSERT lcr will have all the columns that + are being inserted. This WHERE clause could be used to identify the + inserted row after inserting. (like "returning ROWID"). + INSERT INTO TAB(COL1) VALUES (10) -> WHERE COL1=10 + - WHERE clause generated for UPDATE will have all the columns in the + old column list. However the values of the columns will be that of + new value if it exist in the new column list + of the UPDATE. If the column doesnt have new value then the old column + value will be used. + UPDATE TAB SET COL1 = 10 WHERE COL1 = 20 -> WHERE COL1 = 10 + UPDATE TAB SET COL2 = 20 WHERE COL1 = 20 -> WHERE COL1 = 20 + - WHERE clause for DELETE will use the columns and values from + old column lst + - LOB piecewise operations would use the new columns and values for + generating the WHERE clause. +*/ + +sword OCILCRWhereClauseGet( + OCISvcCtx *svchp, + OCIError *errhp, + oratext *wc_stmt, + ub4 *wc_stmt_len, + void *row_lcrp, + ub4 mode); + +/*--------------------- OCILCRRowStmtGet ----------------------------*/ +/* + NAME + OCILCRRowStmtGet - OCI Get Row Statement + DESCRIPTION + Gets the SQL statement for the given ROW LCR. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + row_stmt (OUT) - Sql Statement equivalent to the + LCR has applied + row_stmt_len (IN/OUT) - length of row_stmt buffer + row_lcrp (IN) - row LCR to be converted to SQL + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + None +*/ +sword OCILCRRowStmtGet( + OCISvcCtx *svchp, + OCIError *errhp, + oratext *row_stmt, + ub4 *row_stmt_len, + void *row_lcrp, + ub4 mode); + +/*--------------------- OCILCRWhereClauseWithBindVarGet ----------------------*/ +/* + NAME + OCILCRWhereClauseWithBindVarGet - OCI Get Where clause with binds + DESCRIPTION + Gets the where clause statement with bind variables for the given ROW LCR. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + wc_stmt (OUT) - Sql Stmt equivalent to the LCR + wc_stmt_len (IN/OUT) - length of wc_stmt buffer + num_bind_var (OUT) - Number of bind variables + bind_var_dtyp (OUT) - Array of Data types of bind + variables + bind_var_valuesp (OUT) - Array of Values of bind variables + bind_var_indp (OUT) - Array of null indicators of + bind variables + bind_var_alensp (OUT) - Array of lengths of bind values + bind_var_csetidp (OUT) - Array of char set id of binds + bind_var_csetfp (OUT) - Array of char set form of binds + row_lcrp (IN) - row LCR to be converted to SQL + array_size (IN) - Size of the array of bind values + bind_var_syntax (IN) - Native syntax to be used for binds + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + - For now, specify OCI_DEFAULT for mode + - If array_size is not large enough to accommodate the number of columns + in the requested column list then OCI_ERROR is returned. Expected + array_size is returned through num_bind_var parameter. + - bind_var_syntax for oracle should contain ":". This will generate + positional binds such as :1, :2, :3 etc. For other non-oracle databases + they can give the string that needs to be used for binds. + - WHERE clause generated for INSERT lcr will have all the columns that + are being inserted. This WHERE clause could be used to identify the + inserted row after inserting. (like "returning ROWID"). + INSERT INTO TAB(COL1) VALUES (10) -> WHERE COL1=10 + - WHERE clause generated for UPDATE will have all the columns in the + old column list. However the values of the columns will be that of + new column value of the column if it exist in the new values + of the UPDATE. If the column appears only in the old column then + old column value will be used. + UPDATE TAB SET COL1 = 10 WHERE COL1 = 20 -> WHERE COL1 = 10 + UPDATE TAB SET COL2 = 20 WHERE COL1 = 20 -> WHERE COL1 = 20 + - WHERE clause for DELETE will use the columns and values from + old column lst + - LOB piecewise operations would use the new columns and values for + generating the WHERE clause. +*/ +sword OCILCRWhereClauseWithBindVarGet( + OCISvcCtx *svchp, + OCIError *errhp, + oratext *wc_stmt, + ub4 *wc_stmt_len, + ub2 *num_bind_var, + ub2 *bind_var_dtyp, + void **bind_var_valuesp, + OCIInd *bind_var_indp, + ub2 *bind_var_alensp, + ub2 *bind_var_csetidp, + ub1 *bind_var_csetfp, + void *row_lcrp, + ub2 array_size, + oratext *bind_var_syntax, + ub4 mode); + +/*--------------------- OCILCRRowStmtWithBindVarGet ----------------------*/ +/* + NAME + OCILCRRowStmtWithBindVarGet - OCI Get Row Statement + DESCRIPTION + Gets the SQL statement with bind variables for the given ROW LCR. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + row_stmt (OUT) - Sql Stmt equivalent to the LCR + row_stmt_len (IN/OUT) - length of row_stmt buffer + num_bind_var (OUT) - Number of bind variables + bind_var_dtyp (OUT) - Array of Data types of bind + variables + bind_var_valuesp (OUT) - Array of Values of bind variables + bind_var_indp (OUT) - Array of null indicators of + bind variables + bind_var_alensp (OUT) - Array of lengths od bind values + bind_var_csetidp (OUT) - Array of char set id of binds + bind_var_csetfp (OUT) - Array of char set form of binds + row_lcrp (IN) - row LCR to be converted to SQL + chunk_column_names (OUT) - Array of chunked column names in + lcr + chunk_column_namesl (OUT) - Length of chunk_column_names + chunk_column_flags (OUT) - flags of chunked columns in lcr + Possible bit values are + OCI_LCR_COLUMN_* flags listed + above. + array_size (IN) - Size of the array of bind values + bind_var_syntax (IN) - Native syntax to be used for binds + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + - For now, specify OCI_DEFAULT for mode + - If array_size is not large enough to accommodate the number of columns + in the requested column list then OCI_ERROR is returned. Expected + array_size is returned through num_bind_var parameter. + - bind_var_syntax for oracle should contain ":". This will generate + positional binds such as :1, :2, :3 etc. For other non-oracle databases + they can give the string that needs to be used for binds. +*/ +sword OCILCRRowStmtWithBindVarGet( + OCISvcCtx *svchp, + OCIError *errhp, + oratext *row_stmt, + ub4 *row_stmt_len, + ub2 *num_bind_var, + ub2 *bind_var_dtyp, + void **bind_var_valuesp, + OCIInd *bind_var_indp, + ub2 *bind_var_alensp, + ub2 *bind_var_csetidp, + ub1 *bind_var_csetfp, + void *row_lcrp, + oratext **chunk_column_names, + ub2 *chunk_column_namesl, + oraub8 *chunk_column_flags, + ub2 array_size, + oratext *bind_var_syntax, + ub4 mode); + +/* +------------------------------------------------------------------------------- + NAME + OCILCRSCNsFromPosition - Get SCNs From Position + + DESCRIPTION + Returns the SCN and commit SCN from the given position. + PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + position (IN) - LCR position + position_len (IN) - length of position + scn (OUT) - the SCN stored in position + commit_scn (OUT) - the commit SCN stored in position + mode (IN) - Mode flags (For future extension. Not used + currently) + RETURN + OCI_SUCCESS if the conversion succeeds, OCI_ERROR otherwise. + NOTE + The user must allocate memory for the return numbers. + The input position must conform to the format generated by an XStream + server. +------------------------------------------------------------------------------- +*/ +sword OCILCRSCNsFromPosition(OCISvcCtx *svchp, + OCIError *errhp, + ub1 *position, + ub2 position_len, + OCINumber *scn, + OCINumber *commit_scn, + ub4 mode); + +/* +------------------------------------------------------------------------------- + NAME + OCILCRSCNToPosition - Converts SCN To Position + + DESCRIPTION + Converts an SCN to a position. The generated position can be passed as the + last_position to OCIXStreamOutAttach function to filter the LCRs + with commit SCN less than the given SCN and the LCR's SCN less than the + given SCN. This means the first LCR sent by the Outbound server is either + - a commit LCR at the given SCN, or + - the first LCR of the subsequent transaction with commit SCN greater + than or equal to the given SCN. + PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + position (OUT) - Result position. Must pre-allocate + OCI_LCR_MAX_POSITION_LEN bytes. + position_len (OUT) - Length of position + scn (IN) - The SCN to be stored in position + mode (IN) - Mode flags (for future extension) + RETURN + OCI_SUCCESS if the conversion succeeds, OCI_ERROR otherwise. +------------------------------------------------------------------------------- +*/ +sword OCILCRSCNToPosition(OCISvcCtx *svchp, + OCIError *errhp, + ub1 *position, + ub2 *position_len, + OCINumber *scn, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRLobInfoGet - OCI LCR GET LOB INFO +DESCRIPTION + Returns the LOB information for a given piece-wise LOB LCR. +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + column_name (OUT) - Pointer to the LOB column name. + Optional. If specified then column_name_len must + be specified as well. + column_name_len(OUT) - Length of LOB column name without the NULL + terminator. + column_dty (OUT) - LOB column dty - either SQLT_CHR (for CLOB) or + SQLT_BIN (for BLOB). + column_flag (OUT) - LOB column flag. + Possible bit values are OCI_LCR_COLUMN_* flags + listed above. + offset (OUT) - LOB operation offset in code points. Returned only + for LOB_TRIM and LOB_WRITE operations; otherwise, + a zero is returned. + This is the same as the 'soffset' parameter for + OCILobErase or the 'offset' parameter in + OCILobWrite functions. + size (OUT) - LOB operation size in code points. Returned only + for LOB_TRIM and LOB_ERASE operations; otherwise, + a zero is returned. + This is the same as the 'new_length' parameter in + OCILobTrim or the 'amtp' parameter in OCILobErase + functions. + row_lcrp (IN) - Streams Row LCR pointer + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRLobInfoGet(OCISvcCtx *svchp, + OCIError *errhp, + oratext **column_name, + ub2 *column_name_len, + ub2 *column_dty, + oraub8 *column_flag, + ub4 *offset, + ub4 *size, + void *row_lcrp, + ub4 mode); + +/* +------------------------------------------------------------------------------= +NAME + OCILCRLobInfoSet - OCI LCR SET LOB INFO +DESCRIPTION + Sets the LOB information for a given piece-wise LOB LCR. +PARAMETERS + svchp (IN) - OCI service context + errhp (IN) - OCI Error Handle + column_name (IN) - Pointer to the LOB column name. + column_name_len(IN) - Length of LOB column name without the NULL + terminator. + column_dty (IN) - LOB column dty - either SQLT_CHR (for CLOB) or + SQLT_BIN (for BLOB). + column_flag (IN) - LOB column flag. + Possible bit values are OCI_LCR_COLUMN_* flags + listed above. + offset (IN) - LOB operation offset in code points. Returned only + for LOB_TRIM and LOB_WRITE operations; otherwise, + a zero is returned. + This is the same as the 'soffset' parameter for + OCILobErase or the 'offset' parameter in + OCILobWrite functions. + size (IN) - LOB operation size in code points. Returned only + for LOB_TRIM and LOB_ERASE operations; otherwise, + a zero is returned. + This is the same as the 'new_length' parameter in + OCILobTrim or the 'amtp' parameter in OCILobErase + functions. + row_lcrp (IN/OUT)- Streams Row LCR pointer + mode (IN) - mode +NOTES + - For now, specify OCI_DEFAULT for mode +------------------------------------------------------------------------------= +*/ +sword OCILCRLobInfoSet(OCISvcCtx *svchp, + OCIError *errhp, + oratext *column_name, + ub2 column_name_len, + ub2 column_dty, + oraub8 column_flag, + ub4 offset, + ub4 size, + void *row_lcrp, + ub4 mode); + +/*--------------------------------------------------------------------------- + STREAMS XSTREAM OUT FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------------- OCIXStreamOutAttach -----------------------------*/ +/* + NAME + OCIXStreamOutAttach - OCI Attach to XStreams Out + DESCRIPTION + Given the name of the server process, attach to the outbound server. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle for error reporting + server_name (IN) - Server name. + server_name_len (IN) - Length of server name. + last_position (IN) - last rcv position. (Optional) + last_position_len (IN) - Length of last_position. + mode (IN) - Mode flags (future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + Specify OCI_DEFAULT for the mode parameter. + + The name of the outbound server must be provided because multiple + outbound servers can be configured in one Oracle instance. This call + returns OCI_ERROR if it encounters any error while attaching to the + outbound server. + + The last_position parameter is used to establish the starting point + of the stream. This call returns OCI_ERROR if the specified position + is non-null and less than the server's processed low-watermark; + otherwise, LCRs with position greater than last_position will be + sent to the user. + + If last_position is null then the stream will start from the processed + low-watermark maintained in the server. +*/ + +sword OCIXStreamOutAttach (OCISvcCtx *svchp, OCIError *errhp, + oratext *server_name, ub2 server_name_len, + ub1 *last_position, + ub2 last_position_len, + ub4 mode); + +#define OCIXSTREAM_OUT_ATTACH_RESERVED_1 (0x00000001) + +/*---------------------- OCIXStreamOutProcessedLWMSet ----------------------*/ +/* + NAME + OCIXStreamOutProcessedLWMSet - Set Processed Low-Watermark + DESCRIPTION + Sets the processed low-watermark maintained at the client. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle for error reporting + processed_low_position (IN) - processed low position. + processed_low_position_len (IN) - processed low position length. + mode (IN) - mode for future extension. (Not used + currently). + RETURNS + OCI_SUCCESS or OCI_ERROR. + + NOTES + The processed low-watermark denotes all LCRs at or below this position + have been processed. After successfully attaching to an XStream + outbound server, a local copy of the processed low-watermark is + maintained at the client. Periodically, this watermark is sent to the + server so that archived logs containing already processed transactions + can be purged. + + The following API is used to update the local copy of the processed + low-watermark. It can be called anytime between OCIXStreamOutAttach + and OCIXStreamOutDetach calls. Clients, using the callback mechanism + to stream LCRs from the server, can invoke this API while + in the callback functions. +*/ + +sword OCIXStreamOutProcessedLWMSet (OCISvcCtx *svchp, OCIError *errhp, + ub1 *processed_low_position, + ub2 processed_low_position_len, + ub4 mode); + + +/*-------------------- OCICallbackXStreamOutLCRProcess ----------------------*/ +/* + NAME + OCICallbackXStreamOutLCRProcess - Callback to process each LCR received + DESCRIPTION + This callback is invoked during OCIXStreamOutLCRCallbackReceive + to process each LCR received from the outbound server. + PARAMETERS + usrctxp (IN/OUT) - Ptr to the user context. + lcrp (IN) - Pointer to the LCR just received. + lcrtyp (IN) - LCR type (OCI_LCR_XROW / OCI_LCR_XDDL) + flag (IN) - If OCI_XSTREAM_MORE_ROW_DATA is set, + this means the current LCR has more + chunk data. + RETURNS + This callback function must return OCI_CONTINUE to continue processing + OCIXStreamOutLCRCallbackReceive call. Any return code other than + OCI_CONTINUE signals that the client wants to terminate + OCIXStreamOutLCRCallbackReceive immediately. +*/ +typedef sb4 (*OCICallbackXStreamOutLCRProcess) (void *usrctxp, void *lcrp, + ub1 lcrtyp, oraub8 flag); + + +/*-------------------- OCICallbackXStreamOutChunkProcess --------------------*/ +/* + NAME + OCICallbackXStreamOutChunkProcess - Callback to process each chunk + DESCRIPTION + This callback is invoked during OCIXStreamOutLCRCallbackReceive + to process each chunk in an LCR. + PARAMETERS + usrctxp (IN/OUT) - Ptr to the user context. + column_name (IN) - Column name for the current chunk. + column_name_len (IN) - Length of column name. + column_dty (IN) - Chunk data type (SQLT_CHR or SQLT_BIN). + column_flag (IN) - LCR column flags. Possible bit values are + OCI_LCR_COLUMN_* flags listed above. + column_csid (IN) - Column character set id. Relevant only if + the column is an XMLType column (i.e., + column_flag has OCI_LCR_COLUMN_XML_DATA bit set). + chunk_bytes (IN) - Chunk data length in bytes. + chunk_data (IN) - Chunk data buffer. + flag (IN) - If OCI_XSTREAM_MORE_ROW_DATA is set, this means + the current LCR has more chunks. + RETURNS + This callback function must return OCI_CONTINUE to continue processing + OCIXStreamOutLCRCallbackReceive call. Any return code other than + OCI_CONTINUE signals that the client wants to terminate + OCIXStreamOutLCRCallbackReceive immediately. +*/ +typedef sb4 (*OCICallbackXStreamOutChunkProcess) + (void *usrctxp, oratext *column_name, ub2 column_name_len, + ub2 column_dty, oraub8 column_flag, ub2 column_csid, + ub4 chunk_bytes, ub1 *chunk_data, oraub8 flag); + +/*-------------------- OCIXStreamOutLCRCallbackReceive ----------------------*/ +/* + NAME + OCIXStreamOutLCRCallbackReceive - OCI Receive LCR stream using Callbacks + DESCRIPTION + This API is used to get the LCR stream from the outbound server using + callbacks to gain better performance. The user must supply a callback + function to be invoked for each LCR received. If some row changes + in the stream may contain LOB/LONG/XMLType columns then the data for + those columns are returned to the user in chunks. To receive those row + changes, the user must provide a second callback to be invoked to + process each chunk data. + + If there is an LCR available in the stream, the processlcr_cb function + is invoked immediately. After the processlcr_cb function exits, if the + current LCR contains additional chunks then the processchunk_cb function + is invoked for each chunk belonging to that LCR. + + If there is no LCR in the stream when the idle timeout expires (see + OCI_ATTR_XSTREAM_IDLE_TIMEOUT), this call returns a null LCR with + OCI_SUCCESS code. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle for error reporting + processlcr_cb (IN) - Client callback function for each LCR. + processchunk_cb (IN) - Client callback function for each + chunk. + usrctxp (IN) - Client context. (Optional) + fetch_low_position (OUT)- Fetch low watermark. (Optional) + fetch_low_position_len (OUT)- Fetch low watermark length. + mode (IN) - mode for future extension. (Not used + currently). + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + - The fetch low watermark is used to indicate all transactions + with commit position below this have been received by the XStream + outbound server. + + - If the LCR contains non-chunked column(s), the duration of that LCR is + limited to the processlcr_cb function. If the LCR contains some + chunk data then the duration of the LCR is extended until all the + chunks have been processed (that is, when the flag passing to + processchunk_cb function does not have OCI_XSTREAM_MORE_ROW_DATA flag + set). If the user wants to access the LCR data at a later time, a + copy of the LCR must be made. The client callback should not modify + or free the LCR passing to the callback. + + - The given usrctxp is passed to both callbacks. + + - An ACK interval is the interval in seconds which the outbound + server receives the processed LWM or the inbound server sends + the processed LWM. The default ACK interval is 30 seconds. This + value can be changed by setting the OCI_ATTR_XSTREAM_ACK_INTERVAL + attribute using OCIAttrSet API. This attribute is checked only + during the Attach call; thus, it must be set before invoking this API. + + - The idle timeout is the interval in seconds after which the current + call will terminate if there is no LCR in the stream. The default + idle timeout is one second. This value can be changed by setting the + OCI_ATTR_XSTREAM_IDLE_TIMEOUT attribute using OCIAttrSet API. This + attribute is checked only during the Attach call; thus, it must be + set before invoking this API. + + - The outbound server ends each call at the transaction boundary + after an ACK interval has elapsed from the start of the call + or when the idle timeout expires. This API returns the fetch + low watermark at the end of each call. +*/ +sword OCIXStreamOutLCRCallbackReceive( + OCISvcCtx *svchp, OCIError *errhp, + OCICallbackXStreamOutLCRProcess processlcr_cb, + OCICallbackXStreamOutChunkProcess processchunk_cb, void *usrctxp, + ub1 *fetch_low_position, ub2 *fetch_low_position_len, ub4 mode); + +/*---------------------- OCIXStreamOutLCRReceive -------------------------*/ +/* + NAME + OCIXStreamOutLCRReceive - Receive LCR without using callback + DESCRIPTION + This API is used to receive an LCR from an outbound stream. If there + is an LCR available, this API immediately returns that LCR. The + duration of each LCR is limited to the processlcr_cb function. + When there is no LCR available in the stream, this call returns a + null LCR after the idle timeout (see OCI_ATTR_XSTREAM_IDLE_TIMEOUT) + has expired. + + To avoid network round trip for every OCIXStreamOutLCRReceive call, + the connection is tied to this call to let the server fill up + the network buffer with LCRs so subsequent calls can quickly receive + the LCRs from the network. The server ends each call at the + transaction boundary after an ACK interval has elapsed since the start + of the call or when the idle timeout expires. See + OCI_ATTR_XSTREAM_ACK_INTERVAL & OCI_ATTR_XSTREAM_IDLE_TIMEOUT + attributes. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle for error reporting + lcrp (OUT) - Pointer to the LCR received from the + stream. + lcrtype (OUT) - LCR type (OCI_LCR_XROW / OCI_LCR_XDDL) + flag (OUT) - If OCI_XSTREAM_MORE_ROW_DATA is set, + it means the current LCR has more + chunk data. + fetch_low_position (OUT)- Fetch low watermark. (Optional) + fetch_low_position_len (OUT)- Fetch low watermark length. + mode (IN) - mode for future extension. (Not used + currently). + RETURNS + - OCI_STILL_EXECUTING means the current call is still in progress. The + connection associated with the specified service context handle is + still tied to this call for streaming the LCRs from the server. An + error is returned if the user attempts to use the same connection to + execute any OCI calls that require database round trip, for example, + OCIStmtExecute, OCIStmtFetch, OCILobRead, etc. OCILcr* calls are + local calls; thus, they are valid while the stream is in progress. + - OCI_SUCCESS means the current call is completed. User is free to + execute OCIStmt*, OCILob*, etc. from the same service context. + - OCI_ERROR means the current call encounters some errors. Use + OCIErrorGet to obtain information about the error. + + NOTES + This call always returns a null LCR when the return code is OCI_SUCCESS. + In addition, it returns the fetch low position to denote the outbound + server has received all transactions with commit position lower than or + equal to this value. +*/ + +sword OCIXStreamOutLCRReceive( + OCISvcCtx *svchp, OCIError *errhp, + void **lcrp, + ub1 *lcrtype, + oraub8 *flag, + ub1 *fetch_low_position, + ub2 *fetch_low_position_len, + ub4 mode); + +/*-------------------------- OCIXStreamOutChunkReceive ---------------------*/ +/* + NAME + OCIXStreamOutChunkReceive - Receive Chunk data + DESCRIPTION + Receives next chunk of LCR data from XStream Outbound server. + This API can only be called while OCIXStreamOutLCRReceive call is + in progress. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors should be reported + column_name (OUT) - Name of column for which data is retrieved. + column_name_len (OUT) - Length of column name. + column_dty (OUT) - LCR column data type. + column_flag (OUT) - LCR column flag. Possible bit values are + OCI_LCR_COLUMN_LOB_DATA + OCI_LCR_COLUMN_LONG_DATA + OCI_LCR_COLUMN_EMPTY_LOB + OCI_LCR_COLUMN_LAST_CHUNK + OCI_LCR_COLUMN_AL16UTF16 + OCI_LCR_COLUMN_ENCRYPTED + OCI_LCR_COLUMN_NCLOB + OCI_LCR_COLUMN_XML_DATA + OCI_LCR_COLUMN_XML_DIFF + column_csid (OUT) - Column character set id. This is returned only + if the column is an XMLType column (i.e., + column_flag has OCI_LCR_COLUMN_XML_DATA bit + set). + chunk_bytes (OUT) - Number of bytes in output buffer. + chunk_data (OUT) - Pointer to the chunk data in the LCR. + Client must not de-allocate this pointer. + flag (OUT) - If OCI_XSTREAM_MORE_ROW_DATA is set, it means + the current LCR has more data coming. + mode (IN) - mode for future extension. (Not used currently). + RETURNS + OCI_SUCCESS - Check colname_len and chunk_bytes to determine the + data just read. + OCI_ERROR - Error encountered. Execute OCIErrorGet to get information + about the error. + NOTES + - If the return code is OCI_SUCCESS, client should check chunk_bytes to + determine the # of bytes read and check column_name to determine + which LCR column the data associated with. + + - All the chunks from one LOB/LONG/XMLType column are returned entirely + before the chunk value for the next LOB/LONG/XMLType column is + returned. + + - The is no fixed ordering on how the LOB/LONG/XMLType columns is + returned. Users must check the column name to determine which column. + The column_flag will have OCI_LCR_COLUMN_LAST_CHUNK bit set when this + function returns the last chunk of each column. + + - This call returns a null column name and null chunk data if it's + invoked when the current LCR contains only non-chunked columns. + + - If OCIXStreamOutLCRReceive call returns OCI_XSTREAM_MORE_ROW_DATA flag + then the user must iteratively call OCIXStreamOutChunkReceive to + retrieve all the chunks belonging to the current row change before + calling the next OCIXStreamOutLCRReceive. + +*/ +sword OCIXStreamOutChunkReceive(OCISvcCtx *svchp, OCIError *errhp, + oratext **column_name, ub2 *column_name_len, + ub2 *column_dty, oraub8 *column_flag, + ub2 *column_csid, ub4 *chunk_bytes, + ub1 **chunk_data, oraub8 *flag, ub4 mode); + +/*------------------------- OCIXStreamOutDetach -----------------------------*/ +/* + NAME + OCIXStreamOutDetach - OCI Detach from XStream Out + DESCRIPTION + Detaches from the attached XStream outbound server. This call sends the + current local processed low-watermark to the server before detaching + from the outbound server. The outbound server automatically restarts + after this call. This API returns OCI_ERROR if it is invoked while a + ReceiveLCR call is in progress. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors should be reported + mode (IN) - mode for future extension. (Not used currently). + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + - The processed_low_position is passed to the server so it can update its + copy. This value if provided must be greater than or equal to the + value maintained in the server; otherwise, an error is returned. +*/ +sword OCIXStreamOutDetach (OCISvcCtx *svchp, OCIError *errhp, ub4 mode); + + +/*--------------------------------------------------------------------------- + STREAMS XSTREAM IN FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------------ OCIXStreamInAttach -------------------------------*/ +/* + NAME + OCIXStreamInAttach - OCI XStream In Attach + DESCRIPTION + Attaches to the specified XStream inbound server. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + server_name (IN) - XStream inbound server name. + server_name_len (IN) - Length of server name. + source_name (IN) - source name to identify the data src. + source_name_len (IN) - Length of source name. + last_position (OUT) - Last position received by inbound + server. Optional. If specified must + pre-allocate OCI_LCR_MAX_POSITION_LEN + bytes for return value. + last_position_len (OUT) - Length of last_position. Must be + non-NULL if last_position is non-NULL. + mode (IN) - Mode flags (For future extension. + (Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + The last_position parameter is returned to establish the starting point + to resume the inbound stream. The client should start sending LCRs with + positions greater than the last_position since the inbound server will + ignore all LCRs with positions less than or equal to this value. +*/ + +sword OCIXStreamInAttach( + OCISvcCtx *svchp, + OCIError *errhp, + oratext *server_name, + ub2 server_name_len, + oratext *source_name, + ub2 source_name_len, + ub1 *last_position, + ub2 *last_position_len, + ub4 mode); + +/*-------------------- OCICallbackXStreamInLCRCreate ------------------------*/ +/* + NAME + OCICallbackXStreamInLCRCreate - Callback to create an LCR + DESCRIPTION + This callback is invoked during OCIXStreamInLCRCallbackSend + to create each LCR to be sent to the inbound server. + PARAMETERS + usrctxp (IN/OUT) - Ptr to the user context + lcrp (OUT) - Pointer to the LCR to be sent + lcrtyp (OUT) - LCR type (OCI_LCR_XROW / OCI_LCR_XDDL) + flag (OUT) - If OCI_XSTREAM_MORE_ROW_DATA is set, + this means the current LCR has more + chunk data. + RETURNS + This callback function must return OCI_CONTINUE to continue processing + OCIXStreamInLCRCallbackSend call. Any return code other than + OCI_CONTINUE signals that the client wants to terminate + OCIXStreamInLCRCallbackSend immediately. +*/ +typedef sb4 (*OCICallbackXStreamInLCRCreate)( + void *usrctxp, + void **lcrp, + ub1 *lcrtyp, + oraub8 *flag); + +/*-------------------- OCICallbackXStreamInChunkCreate --------------------*/ +/* + NAME + OCICallbackXStreamInChunkCreate - Callback to create each chunk + DESCRIPTION + This callback is invoked during OCIXStreamInLCRCallbackSend + to create each chunk to be sent to the inbound server. + PARAMETERS + usrctxp (IN/OUT) - Ptr to the user context. + column_name (OUT) - Column name for the current chunk. + column_name_len (OUT) - Length of column name. + column_dty (OUT) - Chunk data type (SQLT_CHR or SQLT_BIN). + column_flag (OUT) - LCR column flags. Possible bit values are + OCI_LCR_COLUMN_* flags listed above. + column_csid (OUT) - Column character set id. Relevant only if + the column is an XMLType column (i.e., + column_flag has OCI_LCR_COLUMN_XML_DATA bit + set). + chunk_bytes (OUT) - Chunk data length in bytes. + chunk_data (OUT) - Chunk data buffer. + flag (OUT) - If OCI_XSTREAM_MORE_ROW_DATA is set, this means + the current LCR has more chunks. + RETURNS + This callback function must return OCI_CONTINUE to continue processing + OCIXStreamInLCRCallbackSend call. Any return code other than + OCI_CONTINUE signals that the client wants to terminate + OCIXStreamInLCRCallbackSend immediately. +*/ +typedef sb4 (*OCICallbackXStreamInChunkCreate)( + void *usrctxp, + oratext **column_name, + ub2 *column_name_len, + ub2 *column_dty, + oraub8 *column_flag, + ub2 *column_csid, + ub4 *chunk_bytes, + ub1 **chunk_data, + oraub8 *flag); + +/*--------------------- OCIXStreamInLCRCallbackSend ------------------------*/ +/* + NAME + OCIXStreamInLCRCallbackSend - OCI XStream In Send LCR to Inbound Server + DESCRIPTION + Sends LCR stream to XStream inbound server using callbacks. + The API invokes createlcr_cb function to obtain each LCR to send to the + server. If the return flag from the createlcr_cb function has + OCI_XSTREAM_MORE_ROW_DATA bit set, then it invokes createchunk_cb + procedure to obtain each chunk. It repeatedly calls createchunk_cb + function while the flag returned from this callback has + OCI_XSTREAM_MORE_ROW_DATA bit set. When this bit is not set, this API + cycles back to invoke createlcr_cb function to get the next LCR. + This cycle is repeated until the createlcr_cb function returns a null + LCR or when an ACK interval has elapsed since the start of the call. + See OCI_ATTR_XSTREAM_ACK_INTERVAL attribute. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + createlcr_cb (IN) - Callback function to be invoked + to generate an LCR for streaming. + Cannot be null. + createchunk_cb (IN) - Callback function to be invoked to + create each chunk. Can be null if the + user does not need to send any LCR with + LOB/LONG/XMLType columns. OCI_ERROR + will be returned if this argument is + null and the user attempts to send an + LCR with additional chunk data. + usrctxp (IN) - Client context to pass to both + callback functions. + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + None +*/ + +sword OCIXStreamInLCRCallbackSend( + OCISvcCtx *svchp, + OCIError *errhp, + OCICallbackXStreamInLCRCreate createlcr_cb, + OCICallbackXStreamInChunkCreate createchunk_cb, + void *userctxp, + ub4 mode); + +/*---------------------------- OCIXStreamInLCRSend --------------------------*/ +/* + NAME + OCIXStreamInLCRSend - OCI XStream In Send LCR to Inbound Server + DESCRIPTION + Sends LCR stream to XStream inbound server without using callbacks. + To avoid a network round trip for every OCIXStreamInLCRSend call, + the connection is tied to this call for at least the duration + specified by the OCI_ATTR_XSTREAM_ACK_INTERVAL attribute. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + lcrp (IN) - Pointer to the LCR to send. Cannot + be null. + lcrtype (IN) - LCR type (OCI_LCR_XROW / OCI_LCR_XDDL) + flag (IN) - If OCI_XSTREAM_MORE_ROW_DATA is set, + it means the current LCR has more + chunk data. + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + - OCI_STILL_EXECUTING means the current call is still in progress. The + connection associated with the specified service context handle is + still tied to this call for streaming the LCRs to the server. An error + is returned if the user attempts to use the same connection to + execute any OCI calls that require database round trip, for example, + OCIStmtExecute, OCIStmtFetch, OCILobRead, etc. OCILcr* calls are + local calls; thus, they are valid while this call is in progress. + - OCI_SUCCESS means the current call is completed. User is free to + execute OCIStmt*, OCILob*, etc. from the same service context. + - OCI_ERROR means this call encounters some errors. Use OCIErrorGet to + obtain information about the error. +*/ +sword OCIXStreamInLCRSend( + OCISvcCtx *svchp, + OCIError *errhp, + void *lcrp, + ub1 lcrtype, + oraub8 flag, + ub4 mode); + +/*----------------------------- OCIXStreamInChunkSend -----------------------*/ +/* + NAME + OCIXStreamInChunkSend - Send Chunk + DESCRIPTION + Sends the given chunk of column data to XStream Inbound server. + This chunk is associated with the LCR that is sent by the + most recent OCIXStreamInLCRSend call prior to this call. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors should be reported + column_name (IN) - Name of column for which data is sent. + Column names must be canonicalized and must + follow Oracle naming conventions. + column_name_len (IN) - Length of column name. + column_dty (IN) - LCR column data type (must be SQLT_CHR or + SQLT_BIN). + column_flag (IN) - LCR column flags. Possible bit values are + OCI_LCR_COLUMN_LOB_DATA + OCI_LCR_COLUMN_LONG_DATA + OCI_LCR_COLUMN_EMPTY_LOB + OCI_LCR_COLUMN_LAST_CHUNK + OCI_LCR_COLUMN_AL16UTF16 + OCI_LCR_COLUMN_ENCRYPTED + OCI_LCR_COLUMN_NCLOB + OCI_LCR_COLUMN_XML_DATA + OCI_LCR_COLUMN_XML_DIFF + column_csid (IN) - Column character set id. This is required only + if the column is an XMLType column (i.e., + column_flag has OCI_LCR_COLUMN_XML_DATA bit set). + chunk_bytes (IN) - Chunk data length in bytes. + chunk_data (IN) - Chunk data buffer. + flag (IN) - If OCI_XSTREAM_MORE_ROW_DATA is set, it means + the current LCR has more data coming. + mode (IN) - mode for future extension. (Not used currently). +RETURNS + OCI_SUCCESS - Successful call. + OCI_ERROR - Error encountered. Execute OCIErrorGet to get information + about the error. +NOTES + - This function must be called while OCIXStreamInLCRSend is in progress. + + - This function is valid only if the associated LCR's cmd type is + INSERT, UPDATE or LOB_WRITE. It can be invoked multiple times for the + same LCR. + + - This API is not valid for LOB_ERASE and LOB_TRIM LCRs. + + - The chunk values for different columns can not be interleaved. If a + column contains multiple chunks, this procedure must be called + consecutively using the same column name before proceeding to a new column. + The ordering in which the LOB/LONG/XMLType column values are set is + irrelevant. + + - The OCI_LCR_COLUMN_LAST_CHUNK must be specified for the last chunk of + each column. + + - Only one column can be specified for LOB_WRITE operation. + + - For NCLOB or varying width CLOB, the input buffer must be in + AL16UTF16 format. + + - For INSERT operation, each LOB/LONG/XMLType column, with value set using + OCIXStreamInChunkSend, must be included in the current LCR's NEW + column list. The value of that LOB/LONG/XMLType column must be set to + null and must have OCI_LCR_COLUMN_EMPTY_LOB flag defined. + +*/ +sword OCIXStreamInChunkSend (OCISvcCtx *svchp, OCIError *errhp, + oratext *column_name, ub2 column_name_len, + ub2 column_dty, oraub8 column_flag, + ub2 column_csid, ub4 chunk_bytes, + ub1 *chunk_data, oraub8 flag, ub4 mode); + +/*--------------------- OCIXStreamInDetach ----------------------------*/ +/* + NAME + OCIXStreamInDetach - OCI XStream In Detach from Inbound Server + DESCRIPTION + Detaches from XStream inbound server and returns the inbound server's + processed low-watermark. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + processed_low_position (OUT) - Inbound server's processed low + position. Must pre-allocate + OCI_LCR_MAX_POSITION_LEN bytes for + output buffer. + processed_low_position_len(OUT)- Processed_low_position length. + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + None +*/ +sword OCIXStreamInDetach( + OCISvcCtx *svchp, + OCIError *errhp, + ub1 *processed_low_position, + ub2 *processed_low_position_len, + ub4 mode); + +/*--------------------- OCIXStreamInProcessedLWMGet -------------------------*/ +/* + NAME + OCIXStreamInProcessedLWMGet - OCI XStream In Get LowWatermark + DESCRIPTION + Returns XStream inbound server's processed low watermark + cached at the client. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + processed_low_position (OUT) - Inbound server's cached processed + low position. Must pre- + allocate OCI_LCR_MAX_POSITION_LEN + bytes for output buffer. + processed_low_position_len (OUT) - Processed_low_position length. + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + None +*/ +sword OCIXStreamInProcessedLWMGet( + OCISvcCtx *svchp, + OCIError *errhp, + ub1 *processed_low_position, + ub2 *processed_low_position_len, + ub4 mode); + +/*-------------------------- OCIXStreamInFlush ------------------------------*/ +/* + NAME + OCIXStreamInFlush - OCI XStream In Flush network + DESCRIPTION + Flushes network and terminates any in-progress OCIXStreamInLCRSend or + OCIXStreamInLCRCallbackSend call associated with the given service handle. + PARAMETERS + svchp (IN/OUT) - OCI service handle + errhp (IN/OUT) - Error Handle to which errors + should be reported + mode (IN) - Mode flags (For future extension. + Not used currently) + RETURNS + OCI_SUCCESS or OCI_ERROR. + NOTES + Each call will incur a database round trip to get the server's processed + low-watermark, which the user can retrieve afterward using + OCIXStreamInProcessedLWMGet API. This API should be called only when + there is no LCR to send to the server and the client wants to know the + progress of the attached inbound server. + + This call returns OCI_ERROR if it is invoked from the callback functions + of OCIXStreamInLCRCallbackSend API. + + Client must have attached to an XStream inbound server prior to calling + this API. +*/ +sword OCIXStreamInFlush( + OCISvcCtx *svchp, + OCIError *errhp, + ub4 mode); + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OCIXSTREAM_ORACLE */ diff --git a/OCI/include/odci.h b/OCI/include/odci.h new file mode 100644 index 0000000..0395f96 --- /dev/null +++ b/OCI/include/odci.h @@ -0,0 +1,798 @@ +/* + * + */ + +/* Copyright (c) 1998, 2006, Oracle. All rights reserved. */ + +/* + NAME + odci.h - Oracle Data Cartridge Interface definitions + + DESCRIPTION + This file contains Oracle Data Cartridge Interface definitions. These + include the ODCI Types and Constants. + + RELATED DOCUMENTS + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + None. + + PRIVATE FUNCTION(S) + None. + + EXAMPLES + + NOTES + - The constants defined here are replica of the constants defined + in ODCIConst Package defined as part of catodci.sql. If you change + these do make the similar change in catodci.sql. + + MODIFIED (MM/DD/YY) + spsundar 09/13/07 - + yhu 06/02/06 - add callproperty for statistics + yhu 05/22/06 - add ODCI_NODATA to speed rebuild empty index or ind. + part. + srirkris 05/09/06 - change ODCIOrderByInfo_ind + srirkris 02/06/06 - add definitions for CDI query. + spsundar 02/17/06 - add fields/types for system managed domain idx + yhu 02/08/06 - add RenameCol Na d RenameTopADT + yhu 03/11/05 - add flags for rename column and rename table + spsundar 11/28/05 - add fields/types for composite domain idx + yhu 12/06/05 - mapping table for local text indexes + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + ayoaz 04/21/03 - add CursorNum to ODCIEnv + abrumm 12/30/02 - Bug #2223225: add define for + ODCI_ARG_DESC_LIST_MAXSIZE + ayoaz 10/14/02 - Add Cardinality to ODCIArgDesc + ayoaz 09/11/02 - add ODCIQueryInfo to ODCIIndexCtx + yhu 09/19/02 - add ODCI_DEBUGGING_ON for ODCIEnv.EnvFlags + hsbedi 10/10/02 - add object number into ODCIExtTableInfo + ayoaz 08/30/02 - add ODCITable2 types + tchorma 07/29/02 - Add ODCIFuncCallInfo type for WITH COLUMN CONTEXT + hsbedi 06/29/02 - External table populate + yhu 07/20/01 - add parallel degree in ODCIIndexInfo. + abrumm 02/20/01 - ODCIExtTableInfo: add AccessParmBlob attribute + abrumm 01/18/01 - ODCIExtTableInfo: add default directory + spsundar 08/24/00 - Update attrbiute positions + abrumm 08/04/00 - external tables changes: ODCIExtTableInfo, constants + tchorma 09/11/00 - Add return code ODCI_FATAL + tchorma 08/08/00 - Add Update Block References Option for Alter Index + ayoaz 08/01/00 - Add ODCI_AGGREGATE_REUSE_CTX + spsundar 06/19/00 - add ODCIEnv type + abrumm 06/27/00 - add defines for ODCIExtTable flags + abrumm 06/04/00 - external tables: ODCIExtTableInfo change; add ODCIEnv + ddas 04/28/00 - extensible optimizer enhancements for 8.2 + yhu 06/05/00 - add a bit in IndexInfoFlags for trans. tblspc + yhu 04/10/00 - add ODCIPartInfo & remove ODCIIndexPartList + abrumm 03/29/00 - external table support + spsundar 02/14/00 - update odci definitions for 8.2 + nagarwal 03/07/99 - bug# 838308 - set estimate_stats=1 + rmurthy 11/09/98 - add blocking flag + ddas 10/31/98 - add ODCI_QUERY_SORT_ASC and ODCI_QUERY_SORT_DESC + ddas 05/26/98 - fix ODCIPredInfo flag bits + rmurthy 06/03/98 - add macro for RegularCall + spsundar 05/08/98 - add constants related to ODCIIndexAlter options + rmurthy 04/30/98 - remove include s.h + rmurthy 04/20/98 - name fixes + rmurthy 04/13/98 - add C mappings for odci types + alsrivas 04/10/98 - adding defines for ODCI_INDEX1 + jsriniva 04/04/98 - Creation + +*/ + +#ifndef OCI_ORACLE +# include +#endif +#ifndef ODCI_ORACLE +# define ODCI_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* The following are short names that are only supported on IBM mainframes + * with the SLSHORTNAME defined. + * With this all subsequent long names will actually be substituted with + * the short names here + */ + +#define ODCIColInfo_ref odcicir +#define ODCIColInfoList odcicil +#define ODCIColInfoList2 odcicil2 +#define ODCIIndexInfo_ref odciiir +#define ODCIPredInfo_ref odcipir +#define ODCIRidList odcirl +#define ODCIIndexCtx_ref odciicr +#define ODCIObject_ref odcior +#define ODCIObjectList odciol +#define ODCIQueryInfo_ref odciqir +#define ODCIFuncInfo_ref odcifir +#define ODCICost_ref odcicr +#define ODCIArgDesc_ref odciadr +#define ODCIArgDescList odciadl +#define ODCIStatsOptions_ref odcisor +#define ODCIColInfo odcici +#define ODCIColInfo_ind odcicii +#define ODCIIndexInfo odciii +#define ODCIIndexInfo_ind odciiii +#define ODCIPredInfo odcipi +#define ODCIPredInfo_ind odcipii +#define ODCIIndexCtx odciic +#define ODCIIndexCtx_ind odciici +#define ODCIObject odcio +#define ODCIObject_ind odcioi +#define ODCIQueryInfo odciqi +#define ODCIQueryInfo_ind odciqii +#define ODCIFuncInfo odcifi +#define ODCIFuncInfo_infd odcifii +#define ODCICost odcic +#define ODCICost_ind odcici +#define ODCIArgDesc odciad +#define ODCIArgDesc_ind odciadi +#define ODCIStatsOptions odciso +#define ODCIStatsOptions_ind odcisoi +#define ODCIPartInfo odcipti +#define ODCIPartInfo_ind odciptii +#define ODCIPartInfo_ref odciptir +#define ODCIExtTableInfo odcixt +#define ODCIExtTableInfo_ind odcixti +#define ODCIExtTableInfo_ref odcixtr +#define ODCIExtTableQCInfo odcixq +#define ODCIExtTableQCInfo_ind odcixqi +#define ODCIExtTableQCInfo_ref odcixqr +#define ODCIFuncCallInfo odcifc +#define ODCIFuncCall_ind odcifci +#define ODCIFuncCall_ref odcifcr +#define ODCIColValList odcicvl +#define ODCIColArrayList odcical +#define ODCIFilterInfoList odciflil +#define ODCIOrderByInfoList odciobil +#define ODCIFilterInfo_ref odciflir +#define ODCIOrderByInfo_ref odciobir +#define ODCICompQueryInfo_ref odcicqir +#define ODCIFilterInfo odcifli +#define ODCIOrderByInfo odciobi +#define ODCICompQueryInfo odcicqi +#define ODCIFilterInfo_ind odciflii +#define ODCIOrderByInfo_ind odciobii +#define ODCICompQueryInfo_ind odcicqii + +#endif /* SLSHORTNAME */ + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* Constants for Return Status */ +#define ODCI_SUCCESS 0 +#define ODCI_ERROR 1 +#define ODCI_WARNING 2 +#define ODCI_ERROR_CONTINUE 3 +#define ODCI_FATAL 4 + +/* Constants for ODCIPredInfo.Flags */ +#define ODCI_PRED_EXACT_MATCH 0x0001 +#define ODCI_PRED_PREFIX_MATCH 0x0002 +#define ODCI_PRED_INCLUDE_START 0x0004 +#define ODCI_PRED_INCLUDE_STOP 0x0008 +#define ODCI_PRED_OBJECT_FUNC 0x0010 +#define ODCI_PRED_OBJECT_PKG 0x0020 +#define ODCI_PRED_OBJECT_TYPE 0x0040 +#define ODCI_PRED_MULTI_TABLE 0x0080 +#define ODCI_PRED_NOT_EQUAL 0x0100 + +/* Constants for QueryInfo.Flags */ +#define ODCI_QUERY_FIRST_ROWS 0x01 +#define ODCI_QUERY_ALL_ROWS 0x02 +#define ODCI_QUERY_SORT_ASC 0x04 +#define ODCI_QUERY_SORT_DESC 0x08 +#define ODCI_QUERY_BLOCKING 0x10 + +/* Constants for ScnFlg(Func /w Index Context) */ +#define ODCI_CLEANUP_CALL 1 +#define ODCI_REGULAR_CALL 2 + +/* Constants for ODCIFuncInfo.Flags */ +#define ODCI_OBJECT_FUNC 0x01 +#define ODCI_OBJECT_PKG 0x02 +#define ODCI_OBJECT_TYPE 0x04 + +/* Constants for ODCIArgDesc.ArgType */ +#define ODCI_ARG_OTHER 1 +#define ODCI_ARG_COL 2 /* column */ +#define ODCI_ARG_LIT 3 /* literal */ +#define ODCI_ARG_ATTR 4 /* object attribute */ +#define ODCI_ARG_NULL 5 +#define ODCI_ARG_CURSOR 6 + +/* Maximum size of ODCIArgDescList array */ +#define ODCI_ARG_DESC_LIST_MAXSIZE 32767 + +/* Constants for ODCIStatsOptions.Options */ +#define ODCI_PERCENT_OPTION 1 +#define ODCI_ROW_OPTION 2 + +/* Constants for ODCIStatsOptions.Flags */ +#define ODCI_ESTIMATE_STATS 0x01 +#define ODCI_COMPUTE_STATS 0x02 +#define ODCI_VALIDATE 0x04 + +/* Constants for ODCIIndexAlter parameter alter_option */ +#define ODCI_ALTIDX_NONE 0 +#define ODCI_ALTIDX_RENAME 1 +#define ODCI_ALTIDX_REBUILD 2 +#define ODCI_ALTIDX_REBUILD_ONL 3 +#define ODCI_ALTIDX_MODIFY_COL 4 +#define ODCI_ALTIDX_UPDATE_BLOCK_REFS 5 +#define ODCI_ALTIDX_RENAME_COL 6 +#define ODCI_ALTIDX_RENAME_TAB 7 +#define ODCI_ALTIDX_MIGRATE 8 + +/* Constants for ODCIIndexInfo.IndexInfoFlags */ +#define ODCI_INDEX_LOCAL 0x0001 +#define ODCI_INDEX_RANGE_PARTN 0x0002 +#define ODCI_INDEX_HASH_PARTN 0x0004 +#define ODCI_INDEX_ONLINE 0x0008 +#define ODCI_INDEX_PARALLEL 0x0010 +#define ODCI_INDEX_UNUSABLE 0x0020 +#define ODCI_INDEX_ONIOT 0x0040 +#define ODCI_INDEX_TRANS_TBLSPC 0x0080 +#define ODCI_INDEX_FUNCTION_IDX 0x0100 +#define ODCI_INDEX_LIST_PARTN 0x0200 + +/* Constants for ODCIIndexInfo.IndexParaDegree */ +#define ODCI_INDEX_DEFAULT_DEGREE 32767 + +/* Constants for ODCIEnv.EnvFlags */ +#define ODCI_DEBUGGING_ON 0x01 +#define ODCI_NODATA 0x02 + +/* Constants for ODCIEnv.CallProperty */ +#define ODCI_CALL_NONE 0 +#define ODCI_CALL_FIRST 1 +#define ODCI_CALL_INTERMEDIATE 2 +#define ODCI_CALL_FINAL 3 +#define ODCI_CALL_REBUILD_INDEX 4 +#define ODCI_CALL_REBUILD_PMO 5 +#define ODCI_CALL_STATSGLOBAL 6 +#define ODCI_CALL_STATSGLOBALANDPARTITION 7 +#define ODCI_CALL_STATSPARTITION 8 + +/* Constants for ODCIExtTableInfo.OpCode */ +#define ODCI_EXTTABLE_INFO_OPCODE_FETCH 1 +#define ODCI_EXTTABLE_INFO_OPCODE_POPULATE 2 + +/* Constants (bit definitions) for ODCIExtTableInfo.Flag */ + /* sampling type: row or block */ +#define ODCI_EXTTABLE_INFO_FLAG_SAMPLE 0x00000001 +#define ODCI_EXTTABLE_INFO_FLAG_SAMPLE_BLOCK 0x00000002 + /* AccessParmClob, AccessParmBlob discriminator */ +#define ODCI_EXTTABLE_INFO_FLAG_ACCESS_PARM_CLOB 0x00000004 +#define ODCI_EXTTABLE_INFO_FLAG_ACCESS_PARM_BLOB 0x00000008 + +/* Constants for ODCIExtTableInfo.IntraSourceConcurrency */ +#define ODCI_TRUE 1 +#define ODCI_FALSE 0 + +/* Constants (bit definitions) for ODCIExtTable{Open,Fetch,Populate,Close} + * Flag argument. + */ +#define ODCI_EXTTABLE_OPEN_FLAGS_QC 0x00000001 /* caller is Query Coord */ +#define ODCI_EXTTABLE_OPEN_FLAGS_SHADOW 0x00000002 /* caller is shadow proc */ +#define ODCI_EXTTABLE_OPEN_FLAGS_SLAVE 0x00000004 /* caller is slave proc */ + +#define ODCI_EXTTABLE_FETCH_FLAGS_EOS 0x00000001 /* end-of-stream on fetch */ + +/* Constants for Flags argument to ODCIAggregateTerminate */ +#define ODCI_AGGREGATE_REUSE_CTX 1 + +/* Constants for ODCIColInfo.Flags */ +#define ODCI_COMP_FILTERBY_COL 0x0001 +#define ODCI_COMP_ORDERBY_COL 0x0002 +#define ODCI_COMP_ORDERDSC_COL 0x0004 +#define ODCI_COMP_UPDATED_COL 0x0008 +#define ODCI_COMP_RENAMED_COL 0x0010 +#define ODCI_COMP_RENAMED_TOPADT 0x0020 + +/* Constants for ODCIOrderByInfo.ExprType */ +#define ODCI_COLUMN_EXPR 1 +#define ODCI_ANCOP_EXPR 2 + +/* Constants for ODCIOrderByInfo.SortOrder */ +#define ODCI_SORT_ASC 1 +#define ODCI_SORT_DESC 2 +#define ODCI_NULLS_FIRST 4 + +/* Constants for ODCIPartInfo.PartOp */ +#define ODCI_ADD_PARTITION 1 +#define ODCI_DROP_PARTITION 2 + +/*--------------------------------------------------------------------------- + ODCI TYPES + ---------------------------------------------------------------------------*/ +/* + * These are C mappings for the OTS types defined in catodci.sql + */ + +typedef OCIRef ODCIColInfo_ref; +typedef OCIArray ODCIColInfoList; +typedef OCIArray ODCIColInfoList2; +typedef OCIRef ODCIIndexInfo_ref; +typedef OCIRef ODCIPredInfo_ref; +typedef OCIArray ODCIRidList; +typedef OCIRef ODCIIndexCtx_ref; +typedef OCIRef ODCIObject_ref; +typedef OCIArray ODCIObjectList; +typedef OCIRef ODCIQueryInfo_ref; +typedef OCIRef ODCIFuncInfo_ref; +typedef OCIRef ODCICost_ref; +typedef OCIRef ODCIArgDesc_ref; +typedef OCIArray ODCIArgDescList; +typedef OCIRef ODCIStatsOptions_ref; +typedef OCIRef ODCIPartInfo_ref; +typedef OCIRef ODCIEnv_ref; +typedef OCIRef ODCIExtTableInfo_ref; /* external table support */ +typedef OCIArray ODCIGranuleList; /* external table support */ +typedef OCIRef ODCIExtTableQCInfo_ref; /* external table support */ +typedef OCIRef ODCIFuncCallInfo_ref; +typedef OCIArray ODCINumberList; +typedef OCIArray ODCIPartInfoList; +typedef OCIArray ODCIColValList; +typedef OCIArray ODCIColArrayList; +typedef OCIArray ODCIFilterInfoList; +typedef OCIArray ODCIOrderByInfoList; +typedef OCIRef ODCIFilterInfo_ref; +typedef OCIRef ODCIOrderByInfo_ref; +typedef OCIRef ODCICompQueryInfo_ref; + +struct ODCIColInfo +{ + OCIString* TableSchema; + OCIString* TableName; + OCIString* ColName; + OCIString* ColTypName; + OCIString* ColTypSchema; + OCIString* TablePartition; + OCINumber ColFlags; + OCINumber ColOrderPos; + OCINumber TablePartitionIden; + OCINumber TablePartitionTotal; +}; +typedef struct ODCIColInfo ODCIColInfo; + +struct ODCIColInfo_ind +{ + OCIInd atomic; + OCIInd TableSchema; + OCIInd TableName; + OCIInd ColName; + OCIInd ColTypName; + OCIInd ColTypSchema; + OCIInd TablePartition; + OCIInd ColFlags; + OCIInd ColOrderPos; + OCIInd TablePartitionIden; + OCIInd TablePartitionTotal; +}; +typedef struct ODCIColInfo_ind ODCIColInfo_ind; + +struct ODCIFuncCallInfo +{ + struct ODCIColInfo ColInfo; +}; + +struct ODCIFuncCallInfo_ind +{ + struct ODCIColInfo_ind ColInfo; +}; + +struct ODCIIndexInfo +{ + OCIString* IndexSchema; + OCIString* IndexName; + ODCIColInfoList* IndexCols; + OCIString* IndexPartition; + OCINumber IndexInfoFlags; + OCINumber IndexParaDegree; + OCINumber IndexPartitionIden; + OCINumber IndexPartitionTotal; +}; +typedef struct ODCIIndexInfo ODCIIndexInfo; + +struct ODCIIndexInfo_ind +{ + OCIInd atomic; + OCIInd IndexSchema; + OCIInd IndexName; + OCIInd IndexCols; + OCIInd IndexPartition; + OCIInd IndexInfoFlags; + OCIInd IndexParaDegree; + OCIInd IndexPartitionIden; + OCIInd IndexPartitionTotal; +}; +typedef struct ODCIIndexInfo_ind ODCIIndexInfo_ind; + +struct ODCIPredInfo +{ + OCIString* ObjectSchema; + OCIString* ObjectName; + OCIString* MethodName; + OCINumber Flags; +}; +typedef struct ODCIPredInfo ODCIPredInfo; + +struct ODCIPredInfo_ind +{ + OCIInd atomic; + OCIInd ObjectSchema; + OCIInd ObjectName; + OCIInd MethodName; + OCIInd Flags; +}; +typedef struct ODCIPredInfo_ind ODCIPredInfo_ind; + +struct ODCIFilterInfo +{ + ODCIColInfo ColInfo; + OCINumber Flags; + OCIAnyData *strt; + OCIAnyData *stop; +}; +typedef struct ODCIFilterInfo ODCIFilterInfo; + +struct ODCIFilterInfo_ind +{ + OCIInd atomic; + ODCIColInfo_ind ColInfo; + OCIInd Flags; + OCIInd strt; + OCIInd stop; +}; +typedef struct ODCIFilterInfo_ind ODCIFilterInfo_ind; + + +struct ODCIOrderByInfo +{ + OCINumber ExprType; + OCIString *ObjectSchema; + OCIString *TableName; + OCIString *ExprName; + OCINumber SortOrder; +}; +typedef struct ODCIOrderByInfo ODCIOrderByInfo; + +struct ODCIOrderByInfo_ind +{ + OCIInd atomic; + OCIInd ExprType; + OCIInd ObjectSchema; + OCIInd TableName; + OCIInd ExprName; + OCIInd SortOrder; +}; +typedef struct ODCIOrderByInfo_ind ODCIOrderByInfo_ind; + + +struct ODCICompQueryInfo +{ + ODCIFilterInfoList *PredInfo; + ODCIOrderByInfoList *ObyInfo; +}; +typedef struct ODCICompQueryInfo ODCICompQueryInfo; + +struct ODCICompQueryInfo_ind +{ + OCIInd atomic; + OCIInd PredInfo; + OCIInd ObyInfo; +}; +typedef struct ODCICompQueryInfo_ind ODCICompQueryInfo_ind; + + +struct ODCIObject +{ + OCIString* ObjectSchema; + OCIString* ObjectName; +}; +typedef struct ODCIObject ODCIObject; + +struct ODCIObject_ind +{ + OCIInd atomic; + OCIInd ObjectSchema; + OCIInd ObjectName; +}; +typedef struct ODCIObject_ind ODCIObject_ind; + +struct ODCIQueryInfo +{ + OCINumber Flags; + ODCIObjectList* AncOps; + ODCICompQueryInfo CompInfo; +}; +typedef struct ODCIQueryInfo ODCIQueryInfo; + + +struct ODCIQueryInfo_ind +{ + OCIInd atomic; + OCIInd Flags; + OCIInd AncOps; + ODCICompQueryInfo_ind CompInfo; +}; +typedef struct ODCIQueryInfo_ind ODCIQueryInfo_ind; + +struct ODCIIndexCtx +{ + struct ODCIIndexInfo IndexInfo; + OCIString* Rid; + struct ODCIQueryInfo QueryInfo; +}; +typedef struct ODCIIndexCtx ODCIIndexCtx; + +struct ODCIIndexCtx_ind +{ + OCIInd atomic; + struct ODCIIndexInfo_ind IndexInfo; + OCIInd Rid; + struct ODCIQueryInfo_ind QueryInfo; +}; +typedef struct ODCIIndexCtx_ind ODCIIndexCtx_ind; + +struct ODCIFuncInfo +{ + OCIString* ObjectSchema; + OCIString* ObjectName; + OCIString* MethodName; + OCINumber Flags; +}; +typedef struct ODCIFuncInfo ODCIFuncInfo; + +struct ODCIFuncInfo_ind +{ + OCIInd atomic; + OCIInd ObjectSchema; + OCIInd ObjectName; + OCIInd MethodName; + OCIInd Flags; +}; +typedef struct ODCIFuncInfo_ind ODCIFuncInfo_ind; + +struct ODCICost +{ + OCINumber CPUcost; + OCINumber IOcost; + OCINumber NetworkCost; + OCIString* IndexCostInfo; +}; +typedef struct ODCICost ODCICost; + +struct ODCICost_ind +{ + OCIInd atomic; + OCIInd CPUcost; + OCIInd IOcost; + OCIInd NetworkCost; + OCIInd IndexCostInfo; +}; +typedef struct ODCICost_ind ODCICost_ind; + +struct ODCIArgDesc +{ + OCINumber ArgType; + OCIString* TableName; + OCIString* TableSchema; + OCIString* ColName; + OCIString* TablePartitionLower; + OCIString* TablePartitionUpper; + OCINumber Cardinality; +}; +typedef struct ODCIArgDesc ODCIArgDesc; + +struct ODCIArgDesc_ind +{ + OCIInd atomic; + OCIInd ArgType; + OCIInd TableName; + OCIInd TableSchema; + OCIInd ColName; + OCIInd TablePartitionLower; + OCIInd TablePartitionUpper; + OCIInd Cardinality; +}; +typedef struct ODCIArgDesc_ind ODCIArgDesc_ind; + +struct ODCIStatsOptions +{ + OCINumber Sample; + OCINumber Options; + OCINumber Flags; +}; +typedef struct ODCIStatsOptions ODCIStatsOptions; + +struct ODCIStatsOptions_ind +{ + OCIInd atomic; + OCIInd Sample; + OCIInd Options; + OCIInd Flags; +}; +typedef struct ODCIStatsOptions_ind ODCIStatsOptions_ind; + +struct ODCIEnv +{ + OCINumber EnvFlags; + OCINumber CallProperty; + OCINumber DebugLevel; + OCINumber CursorNum; +}; +typedef struct ODCIEnv ODCIEnv; + +struct ODCIEnv_ind +{ + OCIInd _atomic; + OCIInd EnvFlags; + OCIInd CallProperty; + OCIInd DebugLevel; + OCIInd CursorNum; +}; +typedef struct ODCIEnv_ind ODCIEnv_ind; + +struct ODCIPartInfo +{ + OCIString* TablePartition; + OCIString* IndexPartition; + OCINumber IndexPartitionIden; + OCINumber PartOp; +}; +typedef struct ODCIPartInfo ODCIPartInfo; + +struct ODCIPartInfo_ind +{ + OCIInd atomic; + OCIInd TablePartition; + OCIInd IndexPartition; + OCIInd IndexPartitionIden; + OCIInd PartOp; +}; +typedef struct ODCIPartInfo_ind ODCIPartInfo_ind; + +/*---------- External Tables ----------*/ +struct ODCIExtTableInfo +{ + OCIString* TableSchema; + OCIString* TableName; + ODCIColInfoList* RefCols; + OCIClobLocator* AccessParmClob; + OCIBlobLocator* AccessParmBlob; + ODCIArgDescList* Locations; + ODCIArgDescList* Directories; + OCIString* DefaultDirectory; + OCIString* DriverType; + OCINumber OpCode; + OCINumber AgentNum; + OCINumber GranuleSize; + OCINumber Flag; + OCINumber SamplePercent; + OCINumber MaxDoP; + OCIRaw* SharedBuf; + OCIString* MTableName; + OCIString* MTableSchema; + OCINumber TableObjNo; +}; +typedef struct ODCIExtTableInfo ODCIExtTableInfo; + +struct ODCIExtTableInfo_ind +{ + OCIInd _atomic; + OCIInd TableSchema; + OCIInd TableName; + OCIInd RefCols; + OCIInd AccessParmClob; + OCIInd AccessParmBlob; + OCIInd Locations; + OCIInd Directories; + OCIInd DefaultDirectory; + OCIInd DriverType; + OCIInd OpCode; + OCIInd AgentNum; + OCIInd GranuleSize; + OCIInd Flag; + OCIInd SamplePercent; + OCIInd MaxDoP; + OCIInd SharedBuf; + OCIInd MTableName; + OCIInd MTableSchema; + OCIInd TableObjNo; +}; +typedef struct ODCIExtTableInfo_ind ODCIExtTableInfo_ind; + +struct ODCIExtTableQCInfo +{ + OCINumber NumGranules; + OCINumber NumLocations; + ODCIGranuleList* GranuleInfo; + OCINumber IntraSourceConcurrency; + OCINumber MaxDoP; + OCIRaw* SharedBuf; +}; +typedef struct ODCIExtTableQCInfo ODCIExtTableQCInfo; + +struct ODCIExtTableQCInfo_ind +{ + OCIInd _atomic; + OCIInd NumGranules; + OCIInd NumLocations; + OCIInd GranuleInfo; + OCIInd IntraSourceConcurrency; + OCIInd MaxDoP; + OCIInd SharedBuf; +}; +typedef struct ODCIExtTableQCInfo_ind ODCIExtTableQCInfo_ind; + +/*********************************************************/ +/* Table Function Info types (used by ODCITablePrepare) */ +/*********************************************************/ + +struct ODCITabFuncInfo +{ + ODCINumberList* Attrs; + OCIType* RetType; +}; +typedef struct ODCITabFuncInfo ODCITabFuncInfo; + +struct ODCITabFuncInfo_ind +{ + OCIInd _atomic; + OCIInd Attrs; + OCIInd RetType; +}; +typedef struct ODCITabFuncInfo_ind ODCITabFuncInfo_ind; + +/*********************************************************************/ +/* Table Function Statistics types (used by ODCIStatsTableFunction) */ +/*********************************************************************/ + +struct ODCITabFuncStats +{ + OCINumber num_rows; +}; +typedef struct ODCITabFuncStats ODCITabFuncStats; + +struct ODCITabFuncStats_ind +{ + OCIInd _atomic; + OCIInd num_rows; +}; +typedef struct ODCITabFuncStats_ind ODCITabFuncStats_ind; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* ODCI_ORACLE */ diff --git a/OCI/include/oratypes.h b/OCI/include/oratypes.h new file mode 100644 index 0000000..03e6e59 --- /dev/null +++ b/OCI/include/oratypes.h @@ -0,0 +1,322 @@ +/* + Copyright (c) 1982, 2008, Oracle and/or its affiliates.All rights reserved. +*/ + +/* + * $Header: oracore3/public/oratypes.h /nt/21 2009/01/01 19:48:06 sabchoud Exp $ + */ + + + +#ifndef ORATYPES +# define ORATYPES +# define SX_ORACLE +# define SX3_ORACLE + + +#ifndef ORASTDDEF +# include +# define ORASTDDEF +#endif + +#ifndef ORALIMITS +# include +# define ORALIMITS +#endif + + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + + +#ifndef lint +typedef unsigned char ub1; +typedef signed char sb1; +#else +#define ub1 unsigned char +#define sb1 signed char +#endif + +#define UB1MAXVAL ((ub1)UCHAR_MAX) +#define UB1MINVAL ((ub1) 0) +#define SB1MAXVAL ((sb1)SCHAR_MAX) +#define SB1MINVAL ((sb1)SCHAR_MIN) +#define MINUB1MAXVAL ((ub1) 255) +#define MAXUB1MINVAL ((ub1) 0) +#define MINSB1MAXVAL ((sb1) 127) +#define MAXSB1MINVAL ((sb1) -127) + + + + +#ifndef lint +typedef unsigned short ub2; +typedef signed short sb2; +#else +#define ub2 unsigned short +#define sb2 signed short +#endif + +#define UB2MAXVAL ((ub2)USHRT_MAX) +#define UB2MINVAL ((ub2) 0) +#define SB2MAXVAL ((sb2) SHRT_MAX) +#define SB2MINVAL ((sb2) SHRT_MIN) +#define MINUB2MAXVAL ((ub2) 65535) +#define MAXUB2MINVAL ((ub2) 0) +#define MINSB2MAXVAL ((sb2) 32767) +#define MAXSB2MINVAL ((sb2)-32767) + + + + +#ifndef lint +typedef unsigned int ub4; +typedef signed int sb4; +#else +#define eb4 int +#define ub4 unsigned int +#define sb4 signed int +#endif + +#define UB4MAXVAL ((ub4)UINT_MAX) +#define UB4MINVAL ((ub4) 0) +#define SB4MAXVAL ((sb4) INT_MAX) +#define SB4MINVAL ((sb4) INT_MIN) +#define MINUB4MAXVAL ((ub4) 4294967295) +#define MAXUB4MINVAL ((ub4) 0) +#define MINSB4MAXVAL ((sb4) 2147483647) +#define MAXSB4MINVAL ((sb4)-2147483647) + + +/* --- Signed/Unsigned eight-byte scalar (orasb8/oraub8) --- */ + +#define ORAXB8_DEFINED +#ifndef lint +#ifndef __GNUC__ +#ifdef __BORLANDC__ + typedef unsigned __int64 oraub8; + typedef signed __int64 orasb8; +#else + typedef unsigned _int64 oraub8; + typedef signed _int64 orasb8; +#endif /* __BORLANDC__ */ +#else + typedef unsigned long long oraub8; + typedef signed long long orasb8; +#endif + typedef oraub8 ub8; + typedef orasb8 sb8; +#else +# define ub8 oraub8 +# define sb8 orasb8 +# define oraub8 unsigned _int64 +# define orasb8 signed _int64 +#endif /* !lint */ + +#define ORAUB8MINVAL ((oraub8)0) +#define ORAUB8MAXVAL ((oraub8)18446744073709551615) +#define ORASB8MINVAL ((orasb8)-9223372036854775808) +#define ORASB8MAXVAL ((orasb8) 9223372036854775807) + +#define MAXORAUB8MINVAL ((oraub8)0) +#define MINORAUB8MAXVAL ((oraub8)18446744073709551615) +#define MAXORASB8MINVAL ((orasb8)-9223372036854775807) +#define MINORASB8MAXVAL ((orasb8) 9223372036854775807) + + +#define UB1BITS CHAR_BIT +#define UB1MASK ((1 << ((uword)CHAR_BIT)) - 1) + + +#ifdef lint +# define oratext unsigned char +#else + typedef unsigned char oratext; +#endif + + +#ifndef lint +typedef char eb1; +typedef short eb2; +typedef int eb4; +#else +# define eb1 char +# define eb2 short +# define eb4 int +#endif + +#define EB1MAXVAL ((eb1)SCHAR_MAX) +#define EB1MINVAL ((eb1) 0) +#define MINEB1MAXVAL ((eb1) 127) +#define MAXEB1MINVAL ((eb1) 0) +#define EB2MAXVAL ((eb2) SHRT_MAX) +#define EB2MINVAL ((eb2) 0) +#define MINEB2MAXVAL ((eb2) 32767) +#define MAXEB2MINVAL ((eb2) 0) +#define EB4MAXVAL ((eb4) INT_MAX) +#define EB4MINVAL ((eb4) 0) +#define MINEB4MAXVAL ((eb4) 2147483647) +#define MAXEB4MINVAL ((eb4) 0) + + + + +#ifndef lint +typedef sb1 b1; +#else +#define b1 sb1 +#endif +#define B1MAXVAL SB1MAXVAL +#define B1MINVAL SB1MINVAL + +#ifndef lint +typedef sb2 b2; +#else +#define b2 sb2 +#endif +#define B2MAXVAL SB2MAXVAL +#define B2MINVAL SB2MINVAL + +#ifndef lint +typedef sb4 b4; +#else +#define b4 sb4 +#endif +# define B4MAXVAL SB4MAXVAL +# define B4MINVAL SB4MINVAL + + +#if !defined(LUSEMFC) +# ifdef lint +# define text unsigned char +# else + typedef oratext text; +# endif +#endif + +#ifdef lint +# define OraText unsigned char +#else + typedef oratext OraText; +#endif + +#ifndef lint +typedef int eword; +typedef unsigned int uword; +typedef signed int sword; +#else +#define eword int +#define uword unsigned int +#define sword signed int +#endif + +#define EWORDMAXVAL ((eword) INT_MAX) +#define EWORDMINVAL ((eword) 0) +#define UWORDMAXVAL ((uword)UINT_MAX) +#define UWORDMINVAL ((uword) 0) +#define SWORDMAXVAL ((sword) INT_MAX) +#define SWORDMINVAL ((sword) INT_MIN) +#define MINEWORDMAXVAL ((eword) 2147483647) +#define MAXEWORDMINVAL ((eword) 0) +#define MINUWORDMAXVAL ((uword) 4294967295) +#define MAXUWORDMINVAL ((uword) 0) +#define MINSWORDMAXVAL ((sword) 2147483647) +#define MAXSWORDMINVAL ((sword) -2147483647) + + +#ifdef _WIN64 + +#ifndef lint +#ifdef __BORLANDC__ +typedef unsigned __int64 ubig_ora; +typedef signed __int64 sbig_ora; +#else +typedef unsigned _int64 ubig_ora; +typedef signed _int64 sbig_ora; +#endif /* End of __BORLANDC__ */ +#else +#define ubig_ora unsigned _int64 +#define sbig_ora signed _int64 +#endif /* End of lint */ + +#define UBIG_ORAMAXVAL ((ubig_ora)_UI64_MAX) +#define UBIG_ORAMINVAL ((ubig_ora) 0) +#define SBIG_ORAMAXVAL ((sbig_ora) _I64_MAX) +#define SBIG_ORAMINVAL ((sbig_ora) _I64_MIN) +#define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295) +#define MAXUBIG_ORAMINVAL ((ubig_ora) 0) +#define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647) +#define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647) + +#else + +#ifndef lint +typedef unsigned long ubig_ora; +typedef signed long sbig_ora; +#else +#define ubig_ora unsigned long +#define sbig_ora signed long +#endif + +#define UBIG_ORAMAXVAL ((ubig_ora)ULONG_MAX) +#define UBIG_ORAMINVAL ((ubig_ora) 0) +#define SBIG_ORAMAXVAL ((sbig_ora) LONG_MAX) +#define SBIG_ORAMINVAL ((sbig_ora) LONG_MIN) +#define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295) +#define MAXUBIG_ORAMINVAL ((ubig_ora) 0) +#define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647) +#define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647) + +#endif /* _WIN64 */ + +#define UBIGORABITS (UB1BITS * sizeof(ubig_ora)) + + +#undef CONST +#define CONST const + + +#define dvoid void + + +typedef void (*lgenfp_t)( void ); + + + +#ifndef ORASYS_TYPES +# include +# define ORASYS_TYPES +#endif + + + +#ifndef boolean +# define boolean int +#endif + + + +#ifdef sparc +# define SIZE_TMAXVAL SB4MAXVAL +#else +# define SIZE_TMAXVAL UB4MAXVAL +#endif + +#define MINSIZE_TMAXVAL (size_t)4294967295 + + +#if !defined(MOTIF) && !defined(LISPL) && !defined(__cplusplus) && !defined(LUSEMFC) +typedef oratext *string; +#endif + +#ifndef lint +typedef unsigned short utext; +#else +#define utext unsigned short +#endif + + +#endif + diff --git a/OCI/include/ori.h b/OCI/include/ori.h new file mode 100644 index 0000000..60ea1b9 --- /dev/null +++ b/OCI/include/ori.h @@ -0,0 +1,2095 @@ +/* Copyright (c) 1994, 2006, Oracle. All rights reserved. */ + +/* + NAME + ORI - OCI navigational interface + + DESCRIPTION + + This section is intended to give a brief introduction to the navigational + interfaces. Readers can refer to the documents listed in the section + 'RELATED DOCUMENTS' for more information. + + PURPOSE + The Oracle Call Interface (OCI) supports navigational access of objects. + In the navigational paradigm, data is represented as a graph of objects + connected by references. Objects in the graph are reached by following + the references. + + OBJECT ENVIRONMENT + + The object environment is initialized when the OCI environment handle is + initialized with the object option. An object environment contains a + heap which buffers type instances in memory. The object environment also + contains an object cache which keeps track of the objects in the object + environment. Readers can refer to the "Functional Specification for + Programmatic Interface" for more information about the object + environment. + + INSTANCE, OBJECT AND VALUE + + An OTS instance is an occurence of a type specified by the Oracle Type + System (OTS). This section describes how an OTS instance can be + represented in OCI. In OCI, an OTS instance can be classified based on + the type, the lifetime and referencability (see the figure below): + + 1) A persistent object is an instance of an object type. A persistent + object resides in a row of a table in the server and can exist longer + than the duration of a session (connection). Persistent objects can be + identified by object references which contain the object identifiers. + A persistent object is obtained by pinning its object reference. + + 2) A transient object is an instance of an object type. A transient + object cannot exist longer than the duration of a session, and it is + used to contain temporary computing results. Transient objects can + also be identified by references which contain transient object + identifiers. + + 3) A value is an instance of an user-defined type (object type or + collection type) or any built-in OTS type. Unlike objects, values of + object types are identified by memory pointers, rather than by + references. + + A value can be standalone or embbeded. A standalone value is usually + obtained by issuing a select statement. OCI also allows the client + program to select a row of object table into a value by issuing a SQL + statement. Thus, a referenceable object (in the database) can be + represented as a value (which cannot be identified by a reference). + A standalone value can also be an out-of-line attribute in an object + (e.g varchar, raw) or an out-of-line element in a collection (e.g. + varchar, raw, object). + + An embedded value is phyiscally included in a containing instance. + An embedded value can be an in-line attribute in an object (e.g. + number, nested object) or an in-line element in a collection. + + All values are considered to be transient by OCI, e.g. OCI does not + support automatic flushing a value to the database, and the client has + to explicitly execute a SQL statement to store a value into the + database. For embedded values, they are flushed when their containing + instance are flushed. + + + OTS instance + | | + v v + object value (type) + | | + v v + persistent transient (lifetime) + + + persistent obj transient obj value + --------------------------------------------------------------- + | | | | object type, | + | type | object type | object type | built-in, | + | | | | collection | + --------------------------------------------------------------- + | maximum | until object | session | session | + | lifetime | is deleted | | | + --------------------------------------------------------------- + | referencable | yes | yes | no | + --------------------------------------------------------------- + | embeddable | no | no | yes | + --------------------------------------------------------------- + + REFERENCEABLE OBJECT, STANDALONE OBJECT, EMBEDDED OBJECT + + In the reminding of this include file, the following term will be used: + 1) The term 'object' can be generally referred to a persistent object, + a transient object, a standalone value of object type, or an embedded + value of object type. + 2) The term 'referenceable object' refers to a persistent object or a + transient object. + 3) The term 'standalone object' refers to a persistent object, a + transient object or a standalone value of object type. + 4) The term 'embedded object' referes to a embbeded value of object + type. + + META ATTRIBUTES + + There is a set of meta-attributes that are defined for standalone + objects. A meta-attribute can be transient or persistent. A + transient meta-attribute is applicable to an instance only when it is + in memory. A persistent meta-attribute can be applicable to an instance + that is in the disk. + + The set of user visible meta-attributes for persistent objects are: + 1) existent (persistent) : Does the object exist? + 2) nullness (persistent) : Null information of the instance + 3) locked (persistent) : Is the object locked? + 4) pinned (transient) : Is the object being accessed by the client? + 5) dirty (transient) : Has the object been modified? + 6) allocation duration (transient) : see below + 7) pin duration (transient) : see below + + The set of user visible meta-attributes for transient objects are: + 1) existent (transient) : Does the object exist? + 2) nullness (transient) : Null information of the instance + 3) pinned (transient) : Is the object being accessed by the client? + 4) dirty (transient) : Has the object been modified? + 4) allocation duration (transient) : see below + 5) pin duration (transient) : see below + + The set of user visible meta-attributes for standalone values of object + type or collections are: + 1) allocation duration (transient) : see below + 2) nullness (transient) : Null information of the instance + (of an object type) + + NULLNESS OF AN INSTANCE + + Each standalone object is associated with a null structure which keeps + the null information about the object. A null indicates the absence of + data. The null structure itself contains null indicators that represent: + 1) atomic nullness : a null value that pertains to the whole object + 2) null status of the individual attribute in the object + + The layout of a null structure in memory resembles that of the object, + except that the null structure has additional indicators to represent + the atomic nullness for each object. + + An non-existent object is different than an object that is atomically + null. A atomically null object is an existing object that has no data. + + MEMORY LAYOUT OF AN OBJECT + + A standalone object in memory is composed of a top level memory chunk, + a null structure and optionally, a number of secondary memory chunks. + For a DEPARTMENT object type, + + OBJECT TYPE department + { + dep_name varchar2(20), + budget number, + manager person, /o person is an object type o/ + employees collection of person + } + + Each instance of DEPARTMENT will has a top level memory chunk which + contains the top level attributes such as dep_name, budget, manager and + employees. The attributes dep_name and employees are themselves pointers + to the additional memory (the secondary memory chunks). The secondary + memory is for the out-of-line attribute (e.g. varray). + + CONSISTENCY MODEL + + Each pin operation behaves like a distinct SQL select. Thus, the object + cache does not guarantee consistency for a graph of objects. In order to + retrieve a consistent graph of objects, the user has to explicitly start + a serializable transaction or a read-only transaction. + + DURATION + In OCI, a duration is used to specify + + 1) the length of memory allocation of an instance + When each instance is allocated, it is associate with an allocation + duration. The memory occupied by the object is freed automatically + at the end of its allocation duration. The allocation duration of an + instance cannot be changed. + + 2) the length of pinning of an object + When each object is pinned, the client has to give a pin duration + which specify the length of time that the object is intended to be + used. It is an user error to specify a pin duration longer than an + allocation duration of the object. An object is completely unpinned + at the end of its pin duration (see OCIObjectUnpin()). + + An OCI program can use the allocation duration and the pin duration to + automatically free the memory of the instances: + 1) Transient objects and values are freed at the end of the allocation + duration. + 2) Persistent objects ARE freed at the end of the allocation duration. + Persistent objects CAN be freed at the end of the pin duration when + the objects are completely unpinned. The persistent objects are said + to be aged out. See OCIObjectUnpin() for more details. + + There are 3 predefined duration: session, transaction, call. The time + spans of these durations are defined based on the programming model + presented by OCI. The call duration is mapped to the transaction + duration in the client-side environment. See oro.h for the macros defined + for these 3 durations. + + A pin duration can be promoted. For example, if an object is pinned with + duration 1, and the object is later pinned with duration 2, the pin + routine will try to find a duration that is longer or equal to the + length of both duration 1 and duration 2. The pin duration of the object + is set to the that duration. The object is automatically unpinned only + after both duration 1 and duration 2 are terminated. + + RELATED DOCUMENTS + "Functional Specification for Oracle Object RDBMS" + "Functional Specification for Programmatic Interfaces" + "Functional Specification for the Oracle Type System (OTS)" + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTIONS + OCIObjectNew - OCI new a standalone instance + OCIObjectPin - OCI pin an object by reference + OCIObjectUnpin - OCI unpin a referenceable object + OCIObjectPinCountReset - OCI reset the pin count of a referenceable object + OCIObjectLock - OCI lock a persistent object + OCIObjectLockNoWait - OCI lock a persistent object + OCIObjectMarkUpdate - OCI mark a referenceable object as updated + OCIObjectUnmark - OCI unmark a dirtied referenceable object + OCIObjectUnmarkByRef - OCI unmark a dirtied object by reference + OCIObjectFree - OCI free a standalone instance + OCIObjectMarkDelete - OCI mark a referenceable object as deleted + OCIObjectMarkDeleteByRef - OCI mark a referenceable object as deleted by + giving a reference + OCIObjectFlush - OCI flush a persistent object + OCIObjectRefresh - OCI refresh a persistent object + OCIObjectCopy - OCI CoPy one object to another + OCIObjectGetTypeRef - OCI get the Type Reference of a standalone object + OCIObjectGetObjectRef - OCI get the Object's Reference + OCIObjectGetInd - OCI get Null Structure of an standalone object + OCIObjectExists - OCI get the existence of a referenceable object + OCIObjectGetProperty - get object property + OCIObjectIsLocked - OCI get the lock status of a referenceable object + OCIObjectIsDirty - OCI get the dirty status of a referenceable object + OCIObjectPinTable - OCI get Table object + OCIObjectArrayPin - OCI pin array of objects + OCIObjectGetPrimayKeyTypeRef - OCI get the Ref for the primary key OID's + type + OCIObjectMakeObjectRef - OCI Create a pk or sys generated REF + + OCIObjectGetNewOID - OCI Create a new Object ID + + OCICacheFlush - OCI flsuh the modified persistent objects in the cache + OCICacheRefresh - OCI refresh persistent objects in the cache + OCICacheUnpin - OCI unpin referenceable objects in the cache + OCICacheFree - OCI free all instances in the environment + OCICacheUnmark - OCI unmark all dirty referenceable objects in the cache + + PRIVATE FUNCTIONS + None + + EXAMPLES + + The following types will be used in the examples in this section: + + OBJECT TYPE professor + ( + varchar2 name; + number department; + number num_of_students; + ); + + OBJECT TYPE course + ( + varchar2 name; + number grade; + ); + + OBJECT TYPE student + ( + vstring name; + number department; + ref advisor; /o advisor is a professor o/ + collection courses; + ); + + EXAMPLE 1 + + Here is a set of examples to illustrate the usages of some of the + orio and oric functions. + + OCIenv *env; /o OCI environment handle o/ + OCIError *err; /o OCI error handle o/ + OCISvcCtx *svc; /o OCI service handle o/ + + void *stu_tbl; /o pointer to the student table o/ + OCIType *stu_tdo; /o student type tdo o/ + + OCIRef *stu2_ref; /o object reference to student object o/ + student *stu1; /o pointer to the student object o/ + student *stu2; /o pointer to the student object o/ + professor *pro; /o pointer to the professor object o/ + + /o Initialize the OCI environment handle, error handle and service + handle and login to the database o/ + ... + + /o CREATE A PERSISTENT OBJECT o/ + + /o get the table object of student o/ + if (OCIObjectPinTable(env, err, svc, "ORACLEU", sizeof("ORACLEU"), + "STUDENT_TABLE", sizeof("STUDENT_TABLE"), (OCIRef *)0, + OCI_DURATION_NULL, &stu_tbl) != OCI_SUCCESS) + /o error handling code o/ + + /o get type object of student o/ + if (OCITypeByName(env, err, svc, "ORACLEU", sizeof("ORACLEU"), + "STUDENT", sizeof("STUDENT"), OCI_DURATION_NULL, OCI_TYPEGET_HEADER, + &stu_tdo) != OCI_SUCCESS) + /o error handling code o/ + + /o create a persistent object 'mark' (of type student) o/ + if (OCIObjectNew(env, err, svc, OCI_TYPECODE_ADT, stu_tdo, stu_tbl, + OCI_DURATION_TRANS, (ub1)FALSE, (void **)&stu1) != OCI_SUCCESS) + /o error handling code o/ + + /o RETRIEVE OBJECTS IN PERSISTENT STORES o/ + + /o Use OCI to retrieve a reference to student object 'joe'. + o The retrieved reference is bound to the variable stu2_ref. + o/ + + /o pin/retrieve the student "joe" by reference o/ + if (OCIObjectPin(env, err, &stu2_ref, (OCIComplexObject *)0, OCI_PIN_ANY, + OCI_DURATION_TRANS, OCI_LOCK_X, &stu2) != OCI_SUCCESS) + /o error handling code o/ + + /o pin/retrieve the advisor of student "joe" by reference o/ + if (OCIObjectPin(env, err, &stu2->advisor, (OCIComplexObject *)0, + OCI_PIN_ANY, OCI_DURATION_TRANS, OCI_LOCK_X, &pro) != OCI_SUCCESS) + /o error handling code o/ + + /o MODIFY OBJECTS o/ + + /o initialize the newly created object "mark" o/ + DISCARD OCIStringAssignText(env, err, "mark", sizeof("mark"), + &stu1->name); + department = 522; + DISCARD OCINumberFromInt(err, &department, sizeof(department), + OCI_NUMBER_UNSIGNED, &stu1->department); + + /o assign advisor to student "mark" o/ + DISCARD OCIRefAssign(env, err, &stu2->advisor, &stu1->advisor); + + /o update student "joe". o/ + department = 533; + DISCARD OCINumberFromInt(err, &department, sizeof(department), + OCI_NUMBER_UNSIGNED, &stu2->department); + DISCARD OCIObjectMarkUpdate(env, err, stu2); + + /o UNPIN OBJECTS AFTER FINSIHED PROCESSING THEM o/ + + /o unpin the student object "mark" o/ + if (OCIObjectUnpin(env, err, stu1) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the student object "joe" o/ + if (OCIObjectUnpin(env, err, stu2) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the professor object o/ + if (OCIObjectUnpin(env, err, pro) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the type object o/ + if (OCIObjectUnpin(env, err, stu_tdo) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the table object o/ + if (OCIObjectUnpin(env, err, stu_tbl) != OCI_SUCCESS) + /o error handling code o/ + + /o FLUSH MODIFIED OBJECTS BACK TO PERSISTENT STORE o/ + + if (OCICacheFlush(env, err, svc, (void *)0, ((OCIRef*)(*)())0, + (OCIRef *)0) != OCI_SUCCESS) + /o error handling code o/ + + /o commit transaction o/ + + END OF EXAMPLE 1 + + NOTES + This file has been subsetted to contain only the routines that will + be in the first release. + + MODIFIED + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + aahluwal 06/03/02 - bug 2360115 + bpalaval 02/09/01 - Change text to oratext. + rkasamse 06/21/00 - add ociobjectgetnewoid + rkasamse 05/24/00 - add OCIObjectSetData + whe 09/01/99 - 976457:check __cplusplus for C++ code + smuralid 10/29/98 - add comments for OCIObjectMakeObjectRef + mkrishna 08/19/98 - change OCIGetPkTypeRef to OCIObjectGetPrimaryKeyTypeR + mkrishna 08/10/98 - add OCIObjectMakeObjectRef & OCIObjectGetPkTypeRef + rkasamse 06/22/98 - add comments for OCIDurationBegin(End) + pmitra 04/01/98 - OCIObjectLockNoWait added + pmitra 11/05/97 - [573769] OCIObjectArrayPin pos parameter cannot be NU + cxcheng 07/29/97 - fix compile for short names + skrishna 07/14/97 - add OCIObjectGetProperty + skrishna 04/30/97 - OCIObjectFlushRefresh: remove duplicate declaration + skrishna 04/24/97 - flag unsupported functions + sthakur 03/20/97 - modify flag argument to OCIObjectFree + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/19/97 - remove short names support + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + sthakur 12/20/96 - fix a typepo in OCIOBjectArrayPin + jboonleu 11/07/96 - modify comments + cxcheng 10/28/96 - more beautification changes + jboonleu 10/24/96 - add flag to OCIObjectFree + jboonleu 10/22/96 - change interface of OCICacheFlush + cxcheng 10/18/96 - rename OCIObjectPinArray to OCIObjectArrayPin + cxcheng 10/14/96 - more renaming of types + jboonleu 10/09/96 - add new interfaces + cxcheng 10/09/96 - more lint fixes + cxcheng 10/08/96 - more lint fixes + jboonleu 09/27/96 - fix lint errors + jboonleu 10/07/96 - beautify ori.h after conversion to long names + cxcheng 10/04/96 - replace short names with long names + sthakur 08/20/96 - add COR context to OCIObjectPin + mluong 07/17/96 - add back orioglk, oriogdr, oriogiv, and oriocur. + jboonleu 07/17/96 - rename refresh option to conherency option + jboonleu 07/16/96 - change comment for cache consistency + jwijaya 07/03/96 - add ANSI prototypes + jboonleu 06/12/96 - update comment + jboonleu 05/08/96 - change description of OCIDurationGetParent + jboonleu 05/01/96 - add OROOCOSFN + skrishna 04/08/96 - change ori*() to take OCIEnv* and OCIError* instead + of oroenv* + jboonleu 01/04/96 - interface change + jboonleu 10/24/95 - support of variable ref + jboonleu 02/15/95 - new interface + sthakur 01/05/95 - pass username to origrgc + skotsovo 12/07/94 - update example + jwijaya 11/15/94 - rename ORONSPTAB to ORONSPEXT + jwijaya 10/06/94 - add namespace to oriopnm() + jwijaya 10/02/94 - connection handle -> connection number + jboonleu 08/16/94 - fix lint errors + jboonleu 07/20/94 - change interface of OCICacheFlush + tanguyen 07/18/94 - add oriocpe, change OCIObjectCopy to oriocps + tcheng 07/15/94 - add init param maximum_sga_heap_size + tcheng 07/13/94 - change origini to get param string + jboonleu 07/05/94 - change sccs string from sccid to a comment + jboonleu 07/01/94 - Add examples to ORIO* and ORIC* functions + tanguyen 06/30/94 - Fix the ORI_ORACLE ifdef + skotsovo 06/27/94 - include all public functions in public functions + list at top of header file + tcheng 06/27/94 - modify comments according to new template + tanguyen 06/24/94 - fix comments for OCIObjectCopy + tcheng 06/24/94 - fix comments in origrgc() + tanguyen 06/21/94 - fix comments and format + tcheng 06/20/94 - commenting origini/trm/err/rgc/urg() functions + tanguyen 06/16/94 - fix descriptions of ref operations + tanguyen 06/16/94 - clarifies refs comparison + tanguyen 05/12/94 - adds more interfaces (OCIObjectMarkUpdate) + jwijaya 05/10/94 - fix examples, add origurg, change origcon to origrgc + tanguyen 05/03/94 - remove unnecessary 'type' argument from + 'OCIObjectCopy' + tanguyen 03/08/94 - clarifies comments + jwijaya 02/16/94 - more questions + jwijaya 02/11/94 - more comments + jwijaya 02/10/94 - identify optional arguments + jwijaya 02/07/94 - Creation +*/ + + +#ifndef ORATYPES +#include +#endif +#ifndef ORO_ORACLE +#include +#endif +#ifndef OCI_ORACLE +#include +#endif +#ifndef ORT_ORACLE +#include +#endif + +#ifndef ORI_ORACLE +#define ORI_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCIDurationBegin origbgu +#define OCIDurationEnd origedu +#define OCIDurationGetParent origpdr +#define OCICacheFlushRefresh oricfrh +#define OCICacheUnpin oricunp +#define OCICacheFree oricfre +#define OCICacheUnmark oricumk +#define OCICacheGetObjects oricgpr +#define OCICacheRegister oricscb +#define OCIObjectUnpin oriounp +#define OCIObjectPinCountReset orioupz +#define OCIObjectLock oriolck +#define OCIObjectLockNoWait oriolnw +#define OCIObjectMarkUpdate orioupd +#define OCIObjectUnmark orioumk +#define OCIObjectUnmarkByRef orioumr +#define OCIObjectAlwaysLatest oriomkl +#define OCIObjectNotAlwaysLatest oriouml +#define OCIObjectMarkDeleteByRef oriordl +#define OCIObjectMarkDelete oriopdl +#define OCIObjectFlush oriofls +#define OCIObjectFlushRefresh oriofrh +#define OCIObjectCopy oriocpy +#define OCIObjectGetTypeRef oriogtr +#define OCIObjectGetObjectRef oriogor +#define OCIObjectGetInd oriogns +#define OCIObjectExists oriogex +#define OCIObjectGetProperty oriogpr +#define OCIObjectRefresh oriorfs +#define OCIObjectPinTable oriogtb +#define OCIObjectGetPrimaryKeyTypeRef oriogpf +#define OCIObjectMakeObjectRef oriomrf + +#define OCIObjectNew orionew +#define OCIObjectPin oriopin +#define OCIObjectFree oriofre +#define OCIObjectArrayPin orioapn +#define OCIObjectIsDirty oriodrt +#define OCIObjectIsDirtied oriodrd +#define OCIObjectIsLoaded orioldd +#define OCICacheFlush oricfls +#define OCICacheRefresh oricrfs + +#endif /* SLSHORTNAME */ + +/*---------------------------------------------------------------------------*/ +/* PUBLIC TYPES AND CONSTANTS */ +/*---------------------------------------------------------------------------*/ + +/* Also see oro.h. */ + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* OBJECT/INSTANCE OPERATIONS */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------- OCIObjectNew ----------------------------------*/ +sword OCIObjectNew( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCITypeCode typecode, OCIType *tdo, void *table, + OCIDuration duration, boolean value, + void **instance ); +/* + NAME: OCIObjectNew - OCI new (create) a standalone instance + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN) - OCI service handle. + typecode (IN) - the typecode of the type of the instance. + tdo (IN, optional) - pointer to the type descriptor object. The + TDO describes the type of the instance that is to be + created. Refer to OCITypeByName() for obtaining a TDO. + The TDO is required for creating a named type (e.g. an + object or a collection). + table (IN, optional) - pointer to a table object which specifies a + table in the server. This parameter can be set to NULL + if no table is given. See the description below to find + out how the table object and the TDO are used together + to determine the kind of instances (persistent, + transient, value) to be created. Also see + OCIObjectPinTable() for retrieving a table object. + duration (IN) - this is an overloaded parameter. The use of this + parameter is based on the kind of the instance that is + to be created. + a) persistent object. This parameter specifies the + pin duration. + b) transient object. This parameter specififes the + allocation duration and pin duration. + c) value. This parameter specifies the allocation + duration. + value (IN) - specifies whether the created object is a value. + If TRUE, then a value is created. Otherwise, a + referenceable object is created. If the instance is + not an object, then this parameter is ignored. + instance (OUT) - address of the newly created instance + + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function creates a new instance of the type specified by the + typecode or the TDO. Based on the parameters 'typecode' (or 'tdo'), + 'value' and 'table', different kinds of instances can be created: + + The parameter 'table' is not NULL? + + yes no + ---------------------------------------------------------------- + | object type (value=TRUE) | value | value | + ---------------------------------------------------------------- + | object type (value=FALSE) | persistent obj | transient obj | + type ---------------------------------------------------------------- + | built-in type | value | value | + ---------------------------------------------------------------- + | collection type | value | value | + ---------------------------------------------------------------- + + This function allocates the top level memory chunk of an OTS instance. + The attributes in the top level memory are initialized (e.g. an + attribute of varchar2 is initialized to a vstring of 0 length). + + If the instance is an object, the object is marked existed but is + atomically null. + + FOR PERSISTENT OBJECTS: + The object is marked dirty and existed. The allocation duration for + the object is session. The object is pinned and the pin duration is + specified by the given parameter 'duration'. + + FOR TRANSIENT OBJECTS: + The object is pinned. The allocation duration and the pin duration are + specified by the given parameter 'duration'. + + FOR VALUES: + The allocation duration is specified by the given parameter 'duration'. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectPin ----------------------------------*/ +sword OCIObjectPin( OCIEnv *env, OCIError *err, OCIRef *object_ref, + OCIComplexObject *corhdl, OCIPinOpt pin_option, + OCIDuration pin_duration, + OCILockOpt lock_option, void **object ); +/* + NAME: OCIObjectPin - OCI pin a referenceable object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object_ref (IN) - the reference to the object. + corhdl (IN) - handle for complex object retrieval. + pin_option (IN) - See description below. + pin_duration (IN) - The duration of which the object is being accesed + by a client. The object is implicitly unpinned at + the end of the pin duration. + If OCI_DURATION_NULL is passed, there is no pin + promotion if the object is already loaded into + the cache. If the object is not yet loaded, then + the pin duration is set to OCI_DURATION_DEFAULT. + lock_option (IN) - lock option (e.g., exclusive). If a lock option + is specified, the object is locked in the server. + See 'oro.h' for description about lock option. + object (OUT) - the pointer to the pinned object. + + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + + This function pins a referenceable object instance given the object + reference. The process of pinning serves three purposes: + + 1) locate an object given its reference. This is done by the object + cache which keeps track of the objects in the object heap. + + 2) notify the object cache that an object is being in use. An object + can be pinned many times. A pinned object will remain in memory + until it is completely unpinned (see OCIObjectUnpin()). + + 3) notify the object cache that a persistent object is being in use + such that the persistent object cannot be aged out. Since a + persistent object can be loaded from the server whenever is needed, + the memory utilization can be increased if a completely unpinned + persistent object can be freed (aged out), even before the + allocation duration is expired. + + Also see OCIObjectUnpin() for more information about unpinning. + + FOR PERSISTENT OBJECTS: + + When pinning a persistent object, if it is not in the cache, the object + will be fetched from the persistent store. The allocation duration of + the object is session. If the object is already in the cache, it is + returned to the client. The object will be locked in the server if a + lock option is specified. + + This function will return an error for a non-existent object. + + A pin option is used to specify the copy of the object that is to be + retrieved: + + 1) If option is OCI_PIN_ANY (pin any), if the object is already + in the environment heap, return this object. Otherwise, the object + is retrieved from the database. This option is useful when the + client knows that he has the exclusive access to the data in a + session. + + 2) If option is OCI_PIN_LATEST (pin latest), if the object is + not cached, it is retrieved from the database. If the object is + cached, it is refreshed with the latest version. See + OCIObjectRefresh() for more information about refreshing. + + 3) If option is OCI_PIN_RECENT (pin recent), if the object is loaded + into the cache in the current transaction, the object is returned. + If the object is not loaded in the current transaction, the object + is refreshed from the server. + + FOR TRANSIENT OBJECTS: + + This function will return an error if the transient object has already + been freed. This function does not return an error if an exclusive + lock is specified in the lock option. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------------ OCIObjectUnpin -----------------------------*/ +sword OCIObjectUnpin( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectUnpin - OCI unpin a referenceable object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to an object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function unpins an object. An object is completely unpinned when + 1) the object was unpinned N times after it has been pinned N times + (by calling OCIObjectPin()). + 2) it is the end of the pin duration + 3) the function OCIObjectPinCountReset() is called + + There is a pin count associated with each object which is incremented + whenever an object is pinned. When the pin count of the object is zero, + the object is said to be completely unpinned. An unpinned object can + be freed without error. + + FOR PERSISTENT OBJECTS: + When a persistent object is completely unpinned, it becomes a candidate + for aging. The memory of an object is freed when it is aged out. Aging + is used to maximize the utilization of memory. An dirty object cannot + be aged out unless it is flushed. + + FOR TRANSIENT OBJECTS: + The pin count of the object is decremented. A transient can be freed + only at the end of its allocation duration or when it is explicitly + deleted by calling OCIObjectFree(). + + FOR VALUE: + This function will return an error for value. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectPinCountReset -----------------------*/ +sword OCIObjectPinCountReset( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectPinCountReset - OCI resets the pin count of a referenceable + object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to an object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function completely unpins an object. When an object is + completely unpinned, it can be freed without error. + + FOR PERSISTENT OBJECTS: + When a persistent object is completely unpinned, it becomes a candidate + for aging. The memory of an object is freed when it is aged out. Aging + is used to maximize the utilization of memory. An dirty object cannot + be aged out unless it is flushed. + + FOR TRANSIENT OBJECTS: + The pin count of the object is decremented. A transient can be freed + only at the end of its allocation duration or when it is explicitly + freed by calling OCIObjectFree(). + + FOR VALUE: + This function will return an error for value. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectLock ---------------------------------*/ +sword OCIObjectLock( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectLock - OCI lock a persistent object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function locks a persistent object at the server. Unlike + OCIObjectLockNoWait() this function waits if another user currently + holds a lock on the desired object. This function + returns an error if: + 1) the object is non-existent. + + This function will return an error for transient objects and values. + The lock of an object is released at the end of a transaction. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*------------------------ OCIObjectLockNoWait ------------------------------*/ +sword OCIObjectLockNoWait( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectLockNoWait - OCI lock a persistent object, do not wait for + the lock, return error if lock not available + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function locks a persistent object at the server. Unlike + OCIObjectLock() this function will not wait if another user holds + the lock on the desired object. This function returns an error if: + 1) the object is non-existent. + 2) the object is currently locked by another user in which + case this function returns with an error. + + This function will return an error for transient objects and values. + The lock of an object is released at the end of a transaction. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*--------------------------- OCIObjectMarkUpdate ---------------------------*/ +sword OCIObjectMarkUpdate( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectMarkUpdate - OCI marks an object as updated + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + FOR PERSISTENT OBJECTS: + This function marks the specified persistent object as updated. The + persistent objects will be written to the server when the object cache + is flushed. The object is not locked or flushed by this function. It + is an error to update a deleted object. + + After an object is marked updated and flushed, this function must be + called again to mark the object as updated if it has been dirtied + after it is being flushed. + + FOR TRANSIENT OBJECTS: + This function marks the specified transient object as updated. The + transient objects will NOT be written to the server. It is an error + to update a deleted object. + + FOR VALUES: + It is an no-op for values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*----------------------------- OCIObjectUnmark -----------------------------*/ +sword OCIObjectUnmark( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectUnmark - OCI unmarks an object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + FOR PERSISTENT OBJECTS AND TRANSIENT OBJECTS: + This function unmarks the specified persistent object as dirty. Changes + that are made to the object will not be written to the server. If the + object is marked locked, it remains marked locked. The changes that + have already made to the object will not be undone implicitly. + + FOR VALUES: + It is an no-op for values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*----------------------------- OCIObjectUnmarkByRef ------------------------*/ +sword OCIObjectUnmarkByRef( OCIEnv *env, OCIError *err, OCIRef *ref ); +/* + NAME: OCIObjectUnmarkByRef - OCI unmarks an object by Ref + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + ref (IN) - reference of the object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + FOR PERSISTENT OBJECTS AND TRANSIENT OBJECTS: + This function unmarks the specified persistent object as dirty. Changes + that are made to the object will not be written to the server. If the + object is marked locked, it remains marked locked. The changes that + have already made to the object will not be undone implicitly. + + FOR VALUES: + It is an no-op for values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectFree ---------------------------------*/ +sword OCIObjectFree( OCIEnv *env, OCIError *err, void *instance, + ub2 flags ); +/* + NAME: OCIObjectFree - OCI free (and unpin) an standalone instance + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to a standalone instance. + flags (IN) - If OCI_OBJECT_FREE_FORCE is set, free the object + even if it is pinned or dirty. + If OCI_OBJECT_FREE_NONULL is set, the null + structure will not be freed. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance to be freed must be standalone. + - If the instance is a referenceable object, the object must be pinned. + DESCRIPTION: + This function deallocates all the memory allocated for an OTS instance, + including the null structure. + + FOR PERSISTENT OBJECTS: + This function will return an error if the client is attempting to free + a dirty persistent object that has not been flushed. The client should + either flush the persistent object or set the parameter 'flag' to + OCI_OBJECT_FREE_FORCE. + + This function will call OCIObjectUnpin() once to check if the object + can be completely unpin. If it succeeds, the rest of the function will + proceed to free the object. If it fails, then an error is returned + unless the parameter 'flag' is set to OCI_OBJECT_FREE_FORCE. + + Freeing a persistent object in memory will not change the persistent + state of that object at the server. For example, the object will + remain locked after the object is freed. + + FOR TRANSIENT OBJECTS: + + This function will call OCIObjectUnpin() once to check if the object + can be completely unpin. If it succeeds, the rest of the function will + proceed to free the object. If it fails, then an error is returned + unless the parameter 'flag' is set to OCI_OBJECT_FREE_FORCE. + + FOR VALUES: + The memory of the object is freed immediately. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*----------------------- OCIObjectMarkDeleteByRef --------------------------*/ +sword OCIObjectMarkDeleteByRef( OCIEnv *env, OCIError *err, + OCIRef *object_ref); +/* + NAME: OCIObjectMarkDeleteByRef - OCI "delete" (and unpin) an object given + a reference + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object_ref (IN) - ref of the object to be deleted + + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function marks the object designated by 'object_ref' as deleted. + + FOR PERSISTENT OBJECTS: + If the object is not loaded, then a temporary object is created and is + marked deleted. Otherwise, the object is marked deleted. + + The object is deleted in the server when the object is flushed. + + FOR TRANSIENT OBJECTS: + The object is marked deleted. The object is not freed until it is + unpinned. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectMarkDelete ---------------------------*/ +sword OCIObjectMarkDelete( OCIEnv *env, OCIError *err, void *instance ); +/* + NAME: OCIObjectMarkDelete - OCI "delete" an instance given a Pointer + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to the instance + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - If the instance is a referenceable object, then it must be pinned. + DESCRIPTION: + + FOR PERSISTENT OBJECTS: + The object is marked deleted. The memory of the object is not freed. + The object is deleted in the server when the object is flushed. + + FOR TRANSIENT OBJECTS: + The object is marked deleted. The memory of the object is not freed. + + FOR VALUES: + This function frees a value immediately. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectFlush -------------------------------*/ +sword OCIObjectFlush( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectFlush - OCI flush a persistent object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function flushes a modified persistent object to the server. + An exclusive lock is obtained implicitly for the object when flushed. + + When the object is written to the server, triggers may be fired. + Objects can be modified by the triggers at the server. To keep the + objects in the object cache being coherent with the database, the + clients can free or refresh the objects in the cache. + + This function will return an error for transient objects and values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------ OCIObjectRefresh ---------------------------------*/ +sword OCIObjectRefresh( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectRefresh - OCI refresh a persistent object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function refreshes an unmarked object with data retrieved from the + latest snapshot in the server. An object should be refreshed when the + objects in the cache are inconsistent with the objects at + the server: + 1) When an object is flushed to the server, triggers can be fired to + modify more objects in the server. The same objects (modified by + the triggers) in the object cache become obsolete. + 2) When the user issues a SQL or executes a PL/SQL procedure to modify + any object in the server, the same object in the cache becomes + obsolete. + + The object that is refreshed will be 'replaced-in-place'. When an + object is 'replaced-in-place', the top level memory of the object will + be reused so that new data can be loaded into the same memory address. + The top level memory of the null structre is also reused. Unlike the + top level memory chunk, the secondary memory chunks may be resized and + reallocated. The client should be careful when holding onto a pointer + to the secondary memory chunk (e.g. assigning the address of a + secondary memory to a local variable), since this pointer can become + invalid after the object is refreshed. + + The object state will be modified as followed after being refreshed: + - existent : set to appropriate value + - pinned : unchanged + - allocation duration : unchanged + - pin duration : unchanged + + This function is an no-op for transient objects or values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectCopy --------------------------------*/ +sword OCIObjectCopy( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + void *source, void *null_source, + void *target, void *null_target, OCIType *tdo, + OCIDuration duration, ub1 option ); +/* + NAME: OCIObjectCopy - OCI copy one instance to another + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - OCI service context handle + source (IN) - pointer to the source instance + null_source (IN) - pointer to the null structure of the source + target (IN) - pointer to the target instance + null_target (IN) - pointer to the null structure of the target + tdo (IN) - the TDO for both source and target + duration (IN) - allocation duration of the target memory + option (IN) - specify the copy option: + OROOCOSFN - Set Reference to Null. All references + in the source will not be copied to the target. The + references in the target are set to null. + REQUIRES: + - a valid OCI environment handle must be given. + - If source or target is referenceable, it must be pinned. + - The target or the containing instance of the target must be already + be instantiated (e.g. created by OCIObjectNew()). + - The source and target instances must be of the same type. If the + source and target are located in a different databases, then the + same type must exist in both databases. + DESCRIPTION: + This function copies the contents of the 'source' instance to the + 'target' instance. This function performs a deep-copy such that the + data that is copied/duplicated include: + a) all the top level attributes (see the exceptions below) + b) all the secondary memory (of the source) that is reachable from the + top level attributes. + c) the null structure of the instance + + Memory is allocated with the specified allocation duration. + + Certain data items are not copied: + a) If the option OCI_OBJECTCOPY_NOREF is specified, then all references + in the source are not copied. Instead, the references in the target + are set to null. + b) If the attribute is a LOB, then it is set to null. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectGetTypeRef --------------------------*/ +sword OCIObjectGetTypeRef( OCIEnv *env, OCIError *err, void *instance, + OCIRef *type_ref ); +/* + NAME: OCIObjectGetTypeRef - get the type reference of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to an standalone instance + type_ref (OUT) - reference to the type of the object. The reference + must already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - If the object is referenceable, the specified object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function returns a reference to the TDO of a standalone instance. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectGetObjectRef -------------------------*/ +sword OCIObjectGetObjectRef( OCIEnv *env, OCIError *err, void *object, + OCIRef *object_ref ); +/* + NAME: OCIObjectGetObjectRef - OCI get the object reference of an + referenceable object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object (IN) - pointer to a persistent object + object_ref (OUT) - reference of the given object. The reference must + already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function returns a reference to the given object. It returns an + error for values. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectMakeObjectRef -----------------------*/ +sword OCIObjectMakeObjectRef( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, void * table, + void **values, ub4 array_len, + OCIRef *object_ref ); +/* + NAME: OCIObjectMakeObjectRef - OCI Create an object reference to a + referenceable object. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - the service context + table (IN) - A pointer to the table object (must be pinned) + attrlist (IN) - A list of values (OCI type values) from which + the ref is to be created. + attrcnt (IN) - The length of the attrlist array. + object_ref (OUT) - reference of the given object. The reference must + already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The specified table object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function creates a reference given the values that make up the + reference and also a pointer to the table object. + Based on the table's OID property, whether it is a pk based OID or + a system generated OID, the function creates a sys-generated REF or + a pk based REF. + In case of system generated REFs pass in a OCIRaw which is 16 bytes + long contatining the sys generated OID. + In case of PK refs pass in the OCI equivalent for numbers, chars etc.. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectGetPrimaryKeyTypeRef --------------- */ +sword OCIObjectGetPrimaryKeyTypeRef( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, void *table, + OCIRef *type_ref ); +/* + NAME: OCIObjectGetPrimaryKeyTypeRef - OCI get the REF to the pk OID type + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - the service context + table (IN) - pointer to the table object + type_ref (OUT) - reference of the pk type. The reference must + already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The specified table object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function returns a reference to the pk type. It returns an + error for values. If the table is not a Pk oid table/view, then + it returns error. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*-------------------------- OCIObjectGetInd --------------------------------*/ +sword OCIObjectGetInd( OCIEnv *env, OCIError *err, void *instance, + void **null_struct ); +/* + NAME: OCIObjectGetInd - OCI get the null structure of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to the instance + null_struct (OUT) - null structure + REQUIRES: + - a valid OCI environment handle must be given. + - The object must be standalone. + - If the object is referenceable, the specified object must be pinned. + DESCRIPTION: + This function returns the null structure of an instance. This function + will allocate the top level memory of the null structure if it is not + already allocated. If an null structure cannot be allocated for the + instance, then an error is returned. This function only works for + ADT or row type instance. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectExists --------------------------------*/ +sword OCIObjectExists(OCIEnv *env, OCIError *err, void *ins, boolean *exist); +/* + NAME: OCIObjectExist - OCI checks if the object exists + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ins (IN) - pointer to an instance + exist (OUT) - return TRUE if the object exists + REQUIRES: + - a valid OCI environment handle must be given. + - The object must be standalone. + - if object is a referenceable, it must be pinned. + DESCRIPTION: + This function returns the existence of an instance. If the instance + is a value, this function always returns TRUE. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectGetProperty ---------------------------*/ +sword OCIObjectGetProperty(OCIEnv *envh, OCIError *errh, const void *obj, + OCIObjectPropId propertyId, + void *property, ub4 *size ); +/* + NAME: OCIObjectGetProperty - OCIObject Get Property of given object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + obj (IN) - object whose property is returned + propertyId (IN) - id which identifies the desired property + property (OUT) - buffer into which the desired property is + copied + size (IN/OUT) - on input specifies the size of the property buffer + passed by caller, on output will contain the + size in bytes of the property returned. + This parameter is required for string type + properties only (e.g OCI_OBJECTPROP_SCHEMA, + OCI_OBJECTPROP_TABLE). For non-string + properties this parameter is ignored since + the size is fixed. + DESCRIPTION: + This function returns the specified property of the object. + The desired property is identified by 'propertyId'. The property + value is copied into 'property' and for string typed properties + the string size is returned via 'size'. + + Objects are classified as persistent, transient and value + depending upon the lifetime and referenceability of the object. + Some of the properties are applicable only to persistent + objects and some others only apply to persistent and + transient objects. An error is returned if the user tries to + get a property which in not applicable to the given object. + To avoid such an error, the user should first check whether + the object is persistent or transient or value + (OCI_OBJECTPROP_LIFETIME property) and then appropriately + query for other properties. + + The different property ids and the corresponding type of + 'property' argument is given below. + + OCI_OBJECTPROP_LIFETIME + This identifies whether the given object is a persistent + object (OCI_OBJECT_PERSISTENT) or a + transient object (OCI_OBJECT_TRANSIENT) or a + value instance (OCI_OBJECT_VALUE). + 'property' argument must be a pointer to a variable of + type OCIObjectLifetime. + + OCI_OBJECTPROP_SCHEMA + This returns the schema name of the table in which the + object exists. An error is returned if the given object + points to a transient instance or a value. If the input + buffer is not big enough to hold the schema name an error + is returned, the error message will communicate the + required size. Upon success, the size of the returned + schema name in bytes is returned via 'size'. + 'property' argument must be an array of type text and 'size' + should be set to size of array in bytes by the caller. + + OCI_OBJECTPROP_TABLE + This returns the table name in which the object exists. An + error is returned if the given object points to a + transient instance or a value. If the input buffer is not + big enough to hold the table name an error is returned, + the error message will communicate the required size. Upon + success, the size of the returned table name in bytes is + returned via 'size'. 'property' argument must be an array + of type text and 'size' should be set to size of array in + bytes by the caller. + + OCI_OBJECTPROP_PIN_DURATION + This returns the pin duration of the object. + An error is returned if the given object points to a value + instance. Valid pin durations are: OCI_DURATION_SESSION and + OCI_DURATION_TRANS. + 'property' argument must be a pointer to a variable of type + OCIDuration. + + OCI_OBJECTPROP_ALLOC_DURATION + This returns the allocation duration of the object. + Valid allocation durations are: OCI_DURATION_SESSION and + OCI_DURATION_TRANS. + 'property' argument must be a pointer to a variable of type + OCIDuration. + + OCI_OBJECTPROP_LOCK + This returns the lock status of the + object. The possible lock status is enumerated by OCILockOpt. + An error is returned if the given object points to a transient + or value instance. + 'property' argument must be a pointer to a variable of + type OCILockOpt. + Note, the lock status of an object can also be retrieved by + calling OCIObjectIsLocked(). + + OCI_OBJECTPROP_MARKSTATUS + This returns the status flag which indicates whether the + object is a new object, updated object and/or deleted object. + The following macros can be used to test the mark status + flag: + + OCI_OBJECT_IS_UPDATED(flag) + OCI_OBJECT_IS_DELETED(flag) + OCI_OBJECT_IS_NEW(flag) + OCI_OBJECT_IS_DIRTY(flag) + + An object is dirty if it is a new object or marked deleted or + marked updated. + An error is returned if the given object points to a transient + or value instance. 'property' argument must be of type + OCIObjectMarkStatus. + + OCI_OBJECTPROP_VIEW + This identifies whether the specified object is a view object + or not. If property value returned is TRUE, it indicates the + object is a view otherwise it is not. + 'property' argument must be of type boolean. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. Possible errors are TBD + */ + +/*---------------------------- OCIObjectIsLocked --------------------------*/ +sword OCIObjectIsLocked( OCIEnv *env, OCIError *err, void *ins, + boolean *lock); +/* + NAME: OCIObjectIsLocked - OCI get the lock status of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ins (IN) - pointer to an instance + lock (OUT) - return value for the lock status. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - If the object is referenceable, the specified object must be pinned. + DESCRIPTION: + This function returns the lock status of an instance. If the instance + is a value, this function always returns FALSE. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectIsDirty ------------------------------*/ +sword OCIObjectIsDirty( OCIEnv *env, OCIError *err, void *ins, + boolean *dirty); +/* + NAME: OCIObjectIsDirty - OCI get the dirty status of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ins (IN) - pointer to an instance + dirty (OUT) - return value for the dirty status. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - if instance is an object, the instance must be pinned. + DESCRIPTION: + This function returns the dirty status of an instance. If the instance + is a value, this function always returns FALSE. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectPinTable -----------------------------*/ +sword OCIObjectPinTable( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + const oratext *schema_name, + ub4 s_n_length, const oratext *object_name, ub4 o_n_length, + const OCIRef *scope_obj_ref, OCIDuration pin_duration, + void ** object ); +/* + NAME: OCIObjectPinTable - OCI get table object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - OCI service context handle + schema_name (IN, optional) - schema name of the table + s_n_length (IN, optional) - length of the schema name + object_name (IN) - name of the table + o_n_length (IN) - length of the table name + scope_obj_ref (IN, optional) - reference of the scoping object + pin_duration (IN) - pin duration. See description in OCIObjectPin(). + object (OUT) - the pinned table object + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function pin a table object with the specified pin duration. + The client can unpin the object by calling OCIObjectUnpin(). See + OCIObjectPin() and OCIObjectUnpin() for more information about pinning + and unpinning. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectArrayPin -------------------------------*/ +sword OCIObjectArrayPin(OCIEnv *env, OCIError *err, OCIRef **ref_array, + ub4 array_size, OCIComplexObject **cor_array, + ub4 cor_array_size, OCIPinOpt pin_option, + OCIDuration pin_duration, OCILockOpt lock, + void **obj_array, ub4 *pos ); +/* + NAME: OCIObjectArrayPin - ORIO array pin + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ref_array (IN) - array of references to be pinned + array_size (IN) - number of elements in the array of references + pin_option (IN) - pin option. See OCIObjectPin(). + pin_duration (IN) - pin duration. See OCIObjectPin(). + lock_option (IN) - lock option. See OCIObjectPin(). + obj_array (OUT) - If this argument is not NULL, the pinned objects + will be returned in the array. The user must + allocate this array with element type being + 'void *'. The size of this array is identical to + 'array'. + pos (OUT) - If there is an error, this argument will contain + the element that is causing the error. Note that + this argument is set to 1 for the first element in + the ref_array. + REQUIRE: + - a valid OCI environment handle must be given. + - If 'obj_array' is not NULL, then it must already be allocated and + the size of 'obj_array' is 'array_size'. + DESCRIPTION: + This function pin an array of references. All the pinned objects are + retrieved from the database in one network roundtrip. If the user + specifies an output array ('obj_array'), then the address of the + pinned objects will be assigned to the elements in the array. See + OCIObjectPin() for more information about pinning. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------------------------------------------------------*/ +/* HEAP/CACHE OPERATIONS */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------- OCICacheFlush ---------------------------------*/ +sword OCICacheFlush( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + void *context, OCIRef *(*get)(void *context, ub1 *last), + OCIRef **ref ); +/* + NAME: OCICacheFlush - OCI flush persistent objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the dirty objects in all connections + will be flushed. + context (IN) [optional] - specifies an user context that is an + argument to the client callback function 'get'. This + parameter is set to NULL if there is no user context. + get (IN) [optional] - an client-defined function which acts an + iterator to retrieve a batch of dirty objects that need + to be flushed. If the function is not NULL, this function + will be called to get a reference of a dirty object. + This is repeated until a null reference is returned by + the client function or the parameter 'last' is set to + TRUE. The parameter 'context' is passed to get() + for each invocation of the client function. This + parameter should be NULL if user callback is not given. + If the object that is returned by the client function is + not a dirtied persistent object, the object is ignored. + All the objects that are returned from the client + function must be from newed or pinned the same service + context, otherwise, an error is signalled. Note that the + returned objects are flushed in the order in which they + are marked dirty. + ref (OUT) [optional] - if there is an error in flushing the + objects, (*ref) will point to the object that + is causing the error. If 'ref' is NULL, then the object + will not be returned. If '*ref' is NULL, then a + reference will be allocated and set to point to the + object. If '*ref' is not NULL, then the reference of + the object is copied into the given space. If the + error is not caused by any of the dirtied object, + the given ref is initalized to be a NULL reference + (OCIRefIsNull(*ref) is TRUE). + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function flushes the modified persistent objects from the + environment heap to the server. The objects are flushed in the order + that they are marked updated or deleted. + + See OCIObjectFlush() for more information about flushing. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCICacheRefresh -------------------------------*/ +sword OCICacheRefresh(OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCIRefreshOpt option, void *context, + OCIRef *(*get)(void *context), OCIRef **ref); +/* + NAME: OCICacheRefresh - OCI ReFreSh persistent objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the persistent objects in all connections + will be refreshed. + option (IN) [optional] - if OCI_REFRESH_LOAD is specified, all + objects that is loaded within the transaction are + refreshed. If the option is OCI_REFERSH_LOAD and the + parameter 'get' is not NULL, this function will ignore + the parameter. + context (IN) [optional] - specifies an user context that is an + argument to the client callback function 'get'. This + parameter is set to NULL if there is no user context. + get (IN) [optional] - an client-defined function which acts an + iterator to retrieve a batch of objects that need to be + refreshed. If the function is not NULL, this function + will be called to get a reference of an object. If + the reference is not NULL, then the object will be + refreshed. These steps are repeated until a null + reference is returned by this function. The parameter + 'context' is passed to get() for each invocation of the + client function. This parameter should be NULL if user + callback is not given. + ref (OUT) [optional] - if there is an error in refreshing the + objects, (*ref) will point to the object that + is causing the error. If 'ref' is NULL, then the object + will not be returned. If '*ref' is NULL, then a + reference will be allocated and set to point to the + object. If '*ref' is not NULL, then the reference of + the object is copied into the given space. If the + error is not caused by any of the object, + the given ref is initalized to be a NULL reference + (OCIRefIsNull(*ref) is TRUE). + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function refreshes all pinned persistent objects. All unpinned + persistent objects are freed. See OCIObjectRefresh() for more + information about refreshing. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCICacheUnpin --------------------------------*/ +sword OCICacheUnpin( OCIEnv *env, OCIError *err, const OCISvcCtx *svc ); +/* + NAME: OCICacheUnpin - OCI UNPin objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the objects in all connections + will be unpinned. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + If a connection is specified, this function completely unpins the + persistent objects in that connection. Otherwise, all persistent + objects in the heap are completely unpinned. All transient objects in + the heap are also completely unpinned. See OCIObjectUnpin() for more + information about unpinning. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*----------------------------- OCICacheFree --------------------------------*/ +sword OCICacheFree( OCIEnv *env, OCIError *err, const OCISvcCtx *svc ); +/* + NAME: OCICacheFree - OCI FREe instances + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the objects in all connections + will be freed. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + If a connection is specified, this function frees the persistent + objects, transient objects and values allocated for that connection. + Otherwise, all persistent objects, transient objects and values in the + heap are freed. Objects are freed regardless of their pin count. See + OCIObjectFree() for more information about freeing an instance. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*---------------------------- OCICacheUnmark -------------------------------*/ +sword OCICacheUnmark( OCIEnv *env, OCIError *err, const OCISvcCtx *svc ); +/* + NAME: OCICacheUnmark - OCI Unmark all dirty objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the objects in all connections + will be unmarked. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + If a connection is specified, this function unmarks all dirty objects + in that connection. Otherwise, all dirty objects in the cache are + unmarked. See OCIObjectUnmark() for more information about unmarking + an object. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + + +sword OCIDurationBegin( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCIDuration parent, OCIDuration *dur ); +/* + NAME: OCIDurationBegin - OCI DURATION BEGIN + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + This should be passed NULL, when cartridge services + are to be used. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN/OUT) - OCI service handle. + parent (IN) - parent for the duration to be started. + dur (OUT) - newly created user duration + REQUIRES: + - a valid OCI environment handle must be given for non-cartridge + services. + - For cartridge services, NULL should be given for environment handle + - A valid service handle must be given in all cases. + DESCRIPTION: + This function starts a new user duration. A user can have multiple + active user durations simultaneously. The user durations do not have + to be nested. + + The object subsystem predefines 3 durations : + 1) session - memory allocated with session duration comes from + the UGA heap (OCI_DURATION_SESSION). A session + duration terminates at the end of the user session. + 2) transaction - memory allocated with transaction duration comes + from the UGA heap (OCI_DURATION_TRANS). A trans- + action duration terminates at the end of the user + transaction. + 3) call - memory allocated with call duration comes from PGA + heap (OCI_DURATION_CALL). A call duration terminates + at the end of the user call. + + Each user duration has a parent duration. A parent duration can be a + predefined duration or another user duration. The relationship between + a user duration and its parent duration (child duration) are: + + 1) An user duration is nested within the parent duration. When its + parent duration terminates, the user duration will also terminate. + 2) The memory allocated with an user duration comes from the heap of + its parent duration. For example, if the parent duration of an + user duration is call, then the memory allocated with the user + duration will also come from the PGA heap. + + This function can be used as both part of cartridge services as well + as without cartridge services. + The difference in the function in the case of cartridge and + non-cartridge services is: + In case of cartridge services, as descibed above a new user + duration is created as a child of the "parent" duration. + But when used for non-cartridge purposes, when a pre-defined + duration is passed in as parent, it is mapped to the cache duration + for that connection (which is created if not already present) and + the new user duration will be child of the cache duration. + + RETURNS: + if environment handle and service handle is null or if error + handle is null return OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + + +sword OCIDurationEnd( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCIDuration duration ); +/* + NAME: OCIDurationEnd - OCI DURATION END + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + This should be passed NULL, when cartridge services + are to be used. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN/OUT) - OCI service handle. + dur (OUT) - a previously created user duration using + OCIDurationBegin() + REQUIRES: + - a valid OCI environment handle must be given for non-cartridge + services. + - For cartridge services, NULL should be given for environment handle + - A valid service handle must be given in all cases. + DESCRIPTION: + This function terminates a user duration. All memory allocated for + this duration is freed. + + This function can be used as both part of cartridge services as well + as without cartridge services. In both cased, the heap duration + is freed and all the allocated memory for that duration is freed. + The difference in the function in the case of cartridge and + non-cartridge services is: + In case of non-cartridge services, if the duration is pre- + defined, the associated cache duration (see OCIDurationBegin()) + is also terminated and the following is done. + 1) The child durations are terminated. + 2) All objects pinned for this duration are unpinned. + 3) All instances allocated for this duration are freed. + + In case of cartridge services, only the heap duration is + freed. All the context entries allocated for that duration are + freed from the context hash table.. + + RETURNS: + if environment handle and service handle is null or if error + handle is null return OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/****************************************************************************** +** DO NOT USE THE FUNCTIONS BELOW! ** +** UNSUPPORTED INTERFACE ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ + +sword OCIDurationGetParent( OCIEnv *env, OCIError *err, + OCIDuration duration, OCIDuration *parent ); + +sword OCIObjectAlwaysLatest( OCIEnv *env, OCIError *err, void *object ); + +sword OCIObjectNotAlwaysLatest( OCIEnv *env, OCIError *err, + void *object ); + +sword OCIObjectFlushRefresh( OCIEnv *env, OCIError *err, void *object); + +sword OCIObjectIsLoaded( OCIEnv *env, OCIError *err, void *ins, + boolean *load); + +sword OCIObjectIsDirtied( OCIEnv *env, OCIError *err, void *ins, + boolean *dirty); + +sword OCICacheGetObjects( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, + OCIObjectProperty property, + void *client_context, + void (*client_callback)( + void *client_context, + void *object )); + +sword OCICacheRegister( OCIEnv *env, OCIError *err, + OCIObjectEvent event, + void *client_context, + void (*client_callback)( + void *client_context, + OCIObjectEvent event, + void *object)); + +sword OCICacheFlushRefresh( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, void *context, + OCIRef *(*get)(void *context, ub1 *last), + OCIRef **ref ); + +sword OCIObjectSetData(OCIEnv *env, OCIError *err, void *obj_hdr, + void *data); + +sword OCIObjectGetNewOID(OCIEnv *env, OCIError *err, OCISvcCtx *svc, + ub1 *oid); + + +#endif /* ORI_ORACLE */ diff --git a/OCI/include/orid.h b/OCI/include/orid.h new file mode 100644 index 0000000..a105f64 --- /dev/null +++ b/OCI/include/orid.h @@ -0,0 +1,373 @@ +/* Copyright (c) 1994, 2006, Oracle. All rights reserved. */ + +/* + Author: Tin Nguyen + Date: 02/07/94 + Source documents: "Functional Specification for C Object Interface, Object + Management Subsystem", "Oracle C Coding Standards + version 2.2", and the header file template + Rule sets: the generic and .h file rule sets + Quality status: not exited + Identification tag: [ one or more letters to identify the .h file ] + Revision code: [ date of the last revision of the .h file ] + + Note to the user of this header file: + + Anything in this header file that is marked private is not supported and + must not be used. Private sections are included in the header file to + improve internal maintenance. + + NAME + + ORID - Oracle Object Interface for Dynamic Data Access + + DESCRIPTION + + This file contains declarations for C object interface functions including + the dynamic object data access operations that allow callers to dynamically + access and manipulate objects; these operations include getting and setting + attributes of an object. These dynamic object operations are for accessing + and manipulation objects whose types are not known at compile-time. + + RELATED DOCUMENTS + + Functional Specification for C Object Interface / Object Management System + + PUBLIC FUNCTIONS + + OCIObjectSetAttr - ORID SET attribute value + OCIObjectGetAttr - ORID GET attribute value + + PRIVATE FUNCTIONS + + None + + EXAMPLES + + EXAMPLE 1 + + /o + o This example illustrates how an interative program can use the dynamic + o attribute access to display and modify attributes of an ADT instance. + o The interactive program does not know the type of the object at + o compile time. + o/ + + void display(adt_ref, object, null_struct, names, names_count, + names_length, indexes, indexes_count) + { + /o Pin the ADT o/ + if (OCIObjectPin(env, &adt_ref, OROOPOCUR, OROOPDTRA, OROOLMNON, &adt) + != OROSTASUC) + /o error handling code o/ + + /o + o Call the type manager to obtain all the attributes in the object. + o Display the content of each attribute in the ADT instance. If the + o attribute is an array, display each element of the array. If the + o attribute is an ADT instance, recursively call this routine to + o display the embedded ADT instance. + o/ + numAttrs = OCITypeAttrs(env, adt); + for (i= 1; i <= numAttrs; i++) + { + /o get attribute descriptor o/ + if (ortgabp(env, adt, i, &ado_ref, &ado) != OROSTASUC) + /o error handling code o/ + + /o get attribute name o/ + names[names_count] = OCITypeElemName(env, ado, + &names_length[names_count]); + + /o dynamically get the attr o/ + if (OCIObjectGetAttr(env, object, null_struct, 0, adt_ref, names, + names_length, names_count+1, indexes, indexes_count, 0, + &null, &null_info, &attr) != OROSTASUC) + /o error handling code o/ + + /o check if attribute is null o/ + if (null) continue; + + /o get typecode of attribute o/ + typecode = OCITypeElemTypeCode(env, ado); + + /o if attribute is a varray, display each element in varray o/ + if (typecode == OCI_TYPECODE_VARRAY) + { + /o get the reference to the type of the element of the array o/ + if (OCITypeElemParameterizedTyper(env, ado, &attr_type_ref) + != OROSTASUC) + /o error handling code o/ + + /o get the size of array o/ + if (orlasiz(env, &attr_type_ref, (orlva *)attr, + &numElm) != OROSTASUC) + /o error handling code o/ + + /o get the typecode of the element of the array o/ + if (ortty2r(env, attr_type_ref, &typecode) != OROSTASUC) + /o error handling code o/ + + /o iterate the array o/ + for (j=0; j < numElm; j++) + { + /o get an element in the array o/ + if (OCIObjectGetAttr(env, attr, null_info, j+1, attr_type_ref, + names, names_length, 0, indexes, 0, 0, &null, &null_info, + &element) != OROSTASUC) + /o error handling code o/ + + /o check if element is null o/ + if (null) continue; + + /o if attr is an ADT instance, recursively call this routine o/ + if (typecode == OCI_TYPECODE_ADT || typecode == + OCI_TYPECODE_UNNAMEDADT) + { + /o display the element as an adt o/ + display(attr_type_ref, element, null_info, names, lengths, + 0, indexes, 0); + } + + /o if attribute is scalar, print the value to the screen o/ + else output_to_screen(element, typecode); + } + } + + /o if attribute is an ADT instance, recursively call this routine o/ + else if (typecode == OCI_TYPECODE_ADT || typecode == + OCI_TYPECODE_UNNAMEDADT) + { + /o get the type ref of the attribute o/ + if (ortgarf(env, ado, &attr_type_ref) != OROSTASUC) + /o error handling code o/ + + display(attr_type_ref, attr, null_info, 0, names, 0, names_length, + indexes, 0); + } + + /o if attribute is scalar, print the value to the screen o/ + else output_to_screen(attr, typecode); + } + } + + /o ******** main routine *********** o/ + .... + + /o + o Allocate the arrays for storing the path expression + o/ + + /o get the tdo of type 'long' o/ + if (orttypget(&env, con, "SYS", sizeof("SYS"), "SINT32", sizeof("SINT32"), + OROOPDSES, &long_ref, &long_tdo) != OROSTASUC) + /o error handling code o/ + + /o get the tdo of type 'varchar' o/ + if (orttypget(&env, con, "SYS", sizeof("SYS"), "SQL_VARCHAR2", + sizeof("SQL_VARCHAR2"), OROOPDSES, &vchar_ref, &vchar_tdo) + != OROSTASUC) + /o error handling code o/ + + /o allocate the varrays for the path expression o/ + if (orlalloc(env, &vchar_ref, MAX_ARR_SIZE, &attr_names) != OROSTASUC) + /o error handling code o/ + + if (orlalloc(env, &long_ref, MAX_ARR_SIZE, &attr_name_lengths) + != OROSTASUC) + /o error handling code o/ + + if (orlalloc(env, &long_ref, MAX_ARR_SIZE, &attr_name_indexes) + != OROSTASUC) + /o error handling code o/ + + /o + o Get an ADT instance. The ref to the ADT instance can be obtained + o by through ORI or OSCI. + o/ + if (OCIObjectPin(env, &obj_ref, OROOPOCUR, OROOPDTRA, OROOLMUPD, &object) + != OROSTASUC) + /o error handling code o/ + + /o get the null structure of the ADT instance o/ + if (OCIObjectGetInd(gp, object, &null_struct) != OROSTASUC) + /o error handling code o/ + + /o + o Get the type of the ADT instance + o/ + + /o find out the type of the ADT instance o/ + if (oriogto(env, object, &adt_ref) != OROSTASUC) + /o error handling code o/ + + /o display the object o/ + display(adt_ref, object, null_struct, attr_names, 0, attr_names_lengths, + attr_names_indexes, 0); + + /o After the object is displayed, the program waits for the user to + o respond. The user modifies the values of an attribute and the + o program generates a path expression for the attribute and calls + o OCIObjectSetAttr() to set the value. + o/ + + if (OCIObjectSetAttr(env, object, null_struct, adt_ref, + (text **)attr_names, (ub4 *)attr_name_lengths, + attr_names_count, (ub4 *)attr_array_indexes, + attr_array_indexes_count, + (void *)0, FALSE, (void *)value) != OROSTASUC) + /o error handling code o/ + + END OF EXAMPLE 1 + + NOTES + + This file has been subsetted to contain only the routines that will + be in the first release. + + MODIFIED + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + aahluwal 06/03/02 - bug 2360115 + bpalaval 02/09/01 - Change text to oratext. + whe 09/01/99 - 976457:check __cplusplus for C++ code + sthakur 09/18/97 - collection indexing not supported + cxcheng 08/05/97 - fix compile with short names + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + cxcheng 10/17/96 - final renaming of functions + jboonleu 10/07/96 - beautify with OCI long names + cxcheng 10/07/96 - change short names to long names for readability + jboonleu 09/27/96 - fix lint + jwijaya 07/03/96 - add ANSI prototypes + jboonleu 04/13/95 - new interface + jwijaya 10/11/94 - fix the sccs header and add namespace + tanguyen 08/22/94 - fix example + tanguyen 08/09/94 - remove Sccsid declaration + tanguyen 07/20/94 - fix OCIObjectSetAttr and OCIObjectGetAttr to + use position descriptor + tanguyen 07/18/94 - change 'object' type to become ptr to object + tanguyen 06/30/94 - Fix the ORID_ORACLE ifdef + tanguyen 06/27/94 - update to template format + skotsovo 05/12/94 - replace ado with attribute position + jweisz 05/11/94 - test new checkin facility + jwijaya 05/05/94 - orienv/ref/typ -> oroenv/ref/typ + jwijaya 02/07/94 - Creation + +*/ + +#ifndef ORATYPES +#include +#endif +#ifndef ORO_ORACLE +#include +#endif +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORID_ORACLE +#define ORID_ORACLE + +#ifdef SLSHORTNAME + +#define OCIObjectSetAttr oridset +#define OCIObjectGetAttr oridget + +#endif /* SLSHORTNAME */ + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ + +/*-------------------------- OCIObjectSetAttr ----------------------------*/ +sword OCIObjectSetAttr( OCIEnv *env, OCIError *err, void *instance, + void *null_struct, struct OCIType *tdo, + const oratext **names, const ub4 *lengths, + const ub4 name_count, const ub4 *indexes, + const ub4 index_count, const OCIInd null_status, + const void *attr_null_struct, const void *attr_value ); +/* + NAME: OCIObjectSetAttr - ORID SET value + PARAMETERS: + env (IN) - OCI environment handle initialized in object mode + err (IN) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + instance (IN) - pointer to an ADT instance + null_struct (IN) - the null structure of the ADT instance or array + tdo (IN) - pointer to the TDO + names (IN) - array of attribute names. This is used to specify + the names of the attributes in the path expression. + lengths (IN) - array of lengths of attribute names. + name_count (IN) - number of element in the array 'names'. + indexes (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4 *)0. + index_count (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4)0. + attr_null_status (IN) - the null status of the attribute if the type of + attribute is primitive. + attr_null_struct (IN) - the null structure of an ADT or collection + attribute. + attr_value (IN) - pointer to the attribute value. + REQUIRES: + DESCRIPTION: + This function set the attribute of the given object with the given + value. The position of the attribute is specified as a path + expression which is an array of names and an array of indexes. + RETURNS: + one of OROSTA* + EXAMPLES: + For path expression stanford.cs.stu[5].addr, the arrays will look like + names = {"stanford", "cs", "stu", "addr"} + lengths = {8, 2, 3, 4} + indexes = {5} + + Also see the above example. + */ + +/*-------------------------- OCIObjectGetAttr ----------------------------*/ +sword OCIObjectGetAttr( OCIEnv *env, OCIError *err, void *instance, + void *null_struct, struct OCIType *tdo, + const oratext **names, const ub4 *lengths, + const ub4 name_count, const ub4 *indexes, + const ub4 index_count, OCIInd *attr_null_status, + void **attr_null_struct, void **attr_value, + struct OCIType **attr_tdo ); +/* + NAME: OCIObjectGetAttr - ORID GET value + PARAMETERS: + env (IN) - OCI environment handle initialized in object mode + err (IN) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + instance (IN) - pointer to an ADT instance + null_struct (IN) - the null structure of the ADT instance or array + tdo (IN) - pointer to the TDO + names (IN) - array of attribute names. This is used to specify + the names of the attributes in the path expression. + lengths (IN) - array of lengths of attribute names. + name_count (IN) - number of element in the array 'names'. + indexes (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4 *)0. + index_count (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4)0. + attr_null_status (OUT) - the null status of the attribute if the type + of attribute is primitive. + attr_null_struct (OUT) - the null structure of an ADT or collection + attribute. + attr_value (OUT) - pointer to the attribute value. + attr_tdo (OUT) - pointer to the TDO of the attribute. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function gets a value from an ADT instance or from an array. + If the parameter 'instance' points to an ADT instance, then the path + expression specifies the location of the attribute in the ADT. + It is assumed that the object is pinned and that the value returned + is valid until the object is unpinned. + RETURNS: + one of OROSTA* + EXAMPLES: + See example in OCIObjectSetAttr(). Also see the above example. + */ + +#endif /* ORID_ORACLE */ diff --git a/OCI/include/orl.h b/OCI/include/orl.h new file mode 100644 index 0000000..5aa3d88 --- /dev/null +++ b/OCI/include/orl.h @@ -0,0 +1,3633 @@ +/* Copyright (c) 1993, 2006, Oracle. All rights reserved. */ + +/* + Author: Srinath Krishnaswamy + Date: 11/24/93 + Source documents: "Functional Specification for C Language Mapping of + OTS Types, Object Management Subsystem", "Oracle C + Coding Standards version 2.2", and the header file + template + Rule sets: the generic and .h file rule sets + Quality status: not exited + Identification tag: [ one or more letters to identify the .h file ] + Revision code: 11/24/93 + + NAME + + ORL - ORacle's external C Language interface to primitive OTS types + + DESCRIPTION + + This header file contains C langauge interface to the OTS primitive + types. The interface includes C mapping of OTS primitive types and + the prototype of the pre-defined operations on the primitive types. + + *********************************************************************** + *** NOTE: The OCI functions for objects requires the *** + *** application to be running in OBJECT mode. That is, during *** + *** process initialization OCIInitialize(), the mode *** + *** specified should be OBJECT mode. *** + ** OCIInitialize(OCI_OBJECT, ..); *** + *********************************************************************** + + RELATED DOCUMENTS + + [1] Krishnaswamy, Srinath and Nguyen, Tin A., "Functional Specification + for C Language Mapping of OTS Types, Object Management Subsystem", + March 1994. + [2] Nguyen, Tin A., "The Open Type System", Oracle Corporation, + February 1994. + [3] Klein, Jonathan D., "Large Field Management", Oracle Corporation, + October 1993. + + PUBLIC FUNCTIONS + + OCI - OCI functions to manipulate Oracle Number, float and decimal + ARITHMETIC + OCINumberInc - OCINumber INCrement (optimized) + OCINumberDec - OCINumber DECrement (optimized) + OCINumberAdd - OCINumber ADD numbers + OCINumberSub - OCINumber SUBtract numbers + OCINumberMul - OCINumber MULtiply numbers + OCINumberDiv - OCINumber DIVide numbers + OCINumberMod - OCINumber MODulo division + OCINumberIntPower - OCINumber integer PoWeR + OCINumberShift - OCINumber decimal ShiFT number + OCINumberNeg - OCINumber NEGate number + OCINumberAbs - OCINumber ABSolute value + OCINumberCeil - OCINumber CEiling of number + OCINumberFloor - OCINumber FLooR of number + OCINumberSqrt - OCINumber SQuare Root of number + OCINumberSign - OCINumber get SIGN of number + NATIVE TYPE CONVERSION + OCINumberToInt - OCINumber convert number TO machine-format Integer + OCINumberFromInt - OCINumber convert machine-format Integer TO Number + OCINumberToReal - OCINumber convert number TO machine-format Real + OCINumberToRealArray - OCINumber convert array of numbers TO + machine-format Real + OCINumberFromReal - OCINumber convert machine-format Real TO Number + TEXT STRING CONVERSION + OCINumberToText - OCINumber convert number TO String + OCINumberFromText - OCINumber convert String TO Number + COMPARISON + OCINumberCmp - OCINumber CoMPare numbers + OCINumberIsZero - OCINumber comparison with ZERo + OCINumberIsInt - OCINumber Is an Integer + ASSIGNMENT + OCINumberAssign - OCINumber ASsiGn number + OCINumberSetZero - OCINumber Set number to Zero value + OCINumberSetPi - OCINumber Set number to Pi + ROUNDING + OCINumberTrunc - OCINumber TRUncate an Oracle number + OCINumberRound - OCINumber ROUnd number + OCINumberPrec - OCINumber round to Precision digits + TRANSCENDENTAL + OCINumberSin - OCINumber SINe + OCINumberArcSin - OCINumber Arc SINe + OCINumberHypSin - OCINumber SiNe Hyperbolic + OCINumberCos - OCINumber COSine + OCINumberArcCos - OCINumber Arc COSine + OCINumberHypCos - OCINumber CoSine Hyperbolic + OCINumberTan - OCINumber TANgent + OCINumberArcTan - OCINumber Arc TANgent + OCINumberArcTan2 - OCINumber Arc TaNgent 2 + OCINumberHypTan - OCINumber TaNgent Hyperbolic + OCINumberPower - OCINumber arbitrary Base EXponentiation + OCINumberExp - OCINumber EXPonentiation to base e + OCINumberLn - OCINumber Logarithm Natural + OCINumberLog - OCINumber LOGarithm to arbitrary base + + OCIDate - OCI functions to manipulate OCI Date + OCIDateToExternal - OCIDate convert date to external form + OCIDateFromExternal - OCIDate convert external form of date into OCIDate + OCIDateAssign - OCIDate Assignment + OCIDateToText - OCIDate convert date TO String + OCIDateFromText - OCIDate convert String TO Date + OCIDateZoneToZone - OCIDate convert date from one time + Zone TO another Zone + OCIDateCompare - OCIDate CoMPare dates + OCIDateAddMonths - OCIDate ADd or subtract Months + OCIDateAddDays - OCIDate ADd or subtract Days + OCIDateLastDay - OCIDate get date of LaST day of month + OCIDateDaysBetween - OCIDate get number of days BeTWeen two dates + OCIDateNextDay - OCIDate get date of Next DaY + OCIDateCheck - OCIDate CHecK if the given date is valid + OCIDateSysDate - OCIDate get current SYStem date and time + + OCIString - OCI String functions to manipulate Variable-length string + OCIStringAssign - OCIString Assign string to string + OCIStringAssignText - OCIString Assign Text string to string + OCIStringResize - OCIString ReSiZe string + OCIStringSize - OCIString get String Size + OCIStringPtr - OCIString get String PoinTeR + OCIStringAllocSize - OCIString get Allocated SiZe + + OCIRaw - OCI Raw functions to manipulate variable-length raW + OCIRawAssignRaw - OCIRaw Assign Raw (of type OCIRaw*) to raw + (of type OCIRaw*) + OCIRawResize - OCIRaw Resize raw + OCIRawSize - OCIRaw get Raw Size + OCIRawPtr - OCIRaw get Raw data Pointer + OCIRawAllocSize - OCIRaw get Allocated Size + + OCIColl - OCI Collection generic functions. These functions can be + used to manipulate both variable-length array (varray) and + nested table. + OCICollSize - OCIColl return current SIZe of the given collection + (in number of elements) + OCICollMax - OCIColl return the MAXimum number of elements in the + collection (i.e. upper-bound) + OCICollGetElem - OCIColl GET pointer to the element at the given + position + OCICollAssignElem - OCIColl assign to element at given index + OCICollAssign - OCIColl ASsiGn collection; perform deep-copy of source + collection to target collection + OCICollAppend - OCIColl aPPend the given element to the end of the + collection + OCICollTrim - OCIColl trim (delete) the given number of elements + from the end of the collection + OCICollIsLocator - OCIColl indicates whether a collection is locator + based or not. + OCIIterCreate - OCIColl Create an ITerator to scan the collection + elements + OCIIterDelete - OCIColl Delete ITerator + OCIIterInit - OCIColl Initialize ITerator to scan the given collection + OCIIterGetCurrent - OCIColl Iterator based, get CURrent + collection element + OCIIterNext - OCIColl Iterator based, get NeXT collection element + OCIIterPrev - OCIColl Iterator based, get PReVious collection element + + OCITable - OCI functions to manipulate nested Table. The OCIColl*() and + OCITable*() functions can be used to manipulate nested table + OCITableDelete(i) - OCITable if element(i) exists then the element is + marked as deleted else the function returns false. So + delete's create "holes". + OCITableExists(i) - OCITable return true iff an element at + position i EXIsts + OCITableFirst - OCITable return the smallest value of i for which + exists(i) is true. + OCITableLast - OCITable return the largest value of i for which + exists(i) is true. + OCITableNext(i) - OCITable return pointer to the smallest position j, + greater than i, such that OCITableExists(j) is true + OCITablePrev(i) - OCITable return pointer to the largest position j, + less than i, such that OCITableExists(j) is true + OCITableSize - OCITable return current SIZe of the given nested table not + including deleted elements + + OCIRef - OCI functions to manipulate object Reference + OCIRefClear - OCIRef CLeaR or nullify a ref + OCIRefAssign - OCIRef ASsiGn a ref to another + OCIRefIsEqual - OCIRef compare two refs for EQUality + OCIRefIsNull - OCIRef test if a ref is NULl + OCIRefFromHex - OCIRef convert a Hexadecimal string TO a Ref + OCIRefToHex - OCIRef convert a ref to a Hexadecimal string + OCIRefHexSize - OCIRef get size of buffer in bytes to store hexadecimal + string + + OBSOLETE: to be replaced by functions from oci.h: + + ORLL - ORL functions to manipulate lob Locators + orllasg - ORLL AsiGn one locator to another + orllequ - ORLL compare two locators for EQUality + orlliini - ORLL Is the locator INItialized? + orllgsz - ORLL Get locator SiZe + orllgcid - ORLL Get Character set ID + + NOTE: The following are specific to FILE lobs: + + orllsnm - ORLL Set directory alias and file NaMe in the locator + orllgnm - ORLL Get directory alias and file NaMe from the locator + + EXAMPLES + + Examples are given in the description of each function where + relevant. + + NOTES + + This file has been subsetted to contain ONLY the routines that will + be in the first release. + + QUESTIONS + + MODIFIED + bkhaladk 08/01/05 - add defn for OCIBinXmlReposCtx + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + rpingte 11/21/02 - Add OCICollGetElemArray and OCINumberToRealArray + aahluwal 06/03/02 - bug 2360115 + gayyappa 02/01/02 - fix 2210776 : change Dom to DOM + whe 09/25/01 - add OCIXMLType & OCIDomDocument opaque types + bpalaval 02/09/01 - Change text to oratext. + rkasamse 09/20/99 - lint changes + whe 09/01/99 - 976457:check __cplusplus for C++ code + hsbedi 08/11/99 - Add macro + rxgovind 10/14/98 - make non exposed calls (OCIRowType etc) private + rxgovind 06/09/98 - update OCIRowTypeCreate + nmantrav 05/11/98 - add OCIRowTypeGetCount + rxgovind 03/29/98 - add OCIRowType and OCIRowData interfaces + jwijaya 05/06/98 - add OCICollIsLocator + rxgovind 03/18/98 - opaque types: move to kolo.h + etucker 02/02/98 - add comments for Dec and Inc + etucker 01/29/98 - Finish core5 integration + rxgovind 11/11/97 - opaque types + etucker 10/28/97 - add ORLN functions for SDK + cxcheng 07/28/97 - remove OCILobLocator #define + skmishra 05/13/97 - stdcc compatibility changes + skrishna 04/25/97 - rename OCINumber*(): Exp Power TanHyp Zero Init + TanToArc Sqr Truncate and Compare + skotsovo 03/31/97 - remove OCILobLocatorSize + skrishna 03/25/97 - remove orld2i and orldi2d + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + skrishna 01/06/97 - update OCITableSize() comments + skrishna 12/27/96 - fix OCIDateGet/OCIDateSet + skrishna 12/12/96 - update OCICollGelElem comments + skrishna 11/07/96 - OCICollGetElem: interface change + skrishna 11/05/96 - add OCIDate Get/Set and OCIDateAssign + cxcheng 10/31/96 - change OCINumberTanHyp to OCINumberHypTan + cxcheng 10/30/96 - #define orll short names to long names + dchatter 10/26/96 - fix some OCI file long names + cxcheng 10/24/96 - remove unnecessary comment in front + cxcheng 10/14/96 - disable long name mapping for LOB functions + skrishna 10/13/96 - continue beautification + skotsovo 10/16/96 - update ocilob names + cxcheng 10/09/96 - add structure members in #define for date/time + cxcheng 10/09/96 - more lint fixes + skrishna 10/09/96 - continue beautification + cxcheng 10/09/96 - more fixes + skrishna 10/09/96 - change fixed-char rep. to orlvstr* + jwijaya 10/08/96 - continue beautification + jwijaya 10/07/96 - beautify + cxcheng 10/07/96 - more changes + cxcheng 10/04/96 - replace short names with long names + skrishna 10/01/96 - orlcsiz, orltsiz: change prototype to take errhdl + skrishna 09/23/96 - fix lint errors + skotsovo 09/23/96 - remove orllmkcur(). + jwijaya 09/17/96 - comments on null ref + skrishna 09/19/96 - change orlraw format + skotsovo 09/19/96 - add orlliini and remove orllnul + skrishna 08/14/96 - orlvstr: change format to ub4 followed by text + jboonleu 08/06/96 - update comment + skotsovo 08/08/96 - revert to locators instead of descriptors as input t + jboonleu 07/23/96 - remove orlrcur + skrishna 07/06/96 - add orltsiz + skrishna 07/05/96 - add orld2i and orldi2d + jwijaya 07/03/96 - add ANSI prototypes + skrishna 06/27/96 - document default string format in orlds2d & orld2s + skrishna 06/25/96 - change max date value + skrishna 06/18/96 - modify orld2s() comments + skotsovo 06/13/96 - orll functions take lob descriptors instead of locat + rxgovind 06/05/96 - change prototype of orlrcur to take ocienvh + skrishna 05/30/96 - support collection trimming + skrishna 05/30/96 - remove orlralo/fre and orllalo/fre instead use + orionew/fre + skrishna 05/28/96 - add orlt*() and modify orla*() + skotsovo 05/23/96 - add orlbl typedefs for pro*c + jboonleu 05/14/96 - add orlrcur + rxgovind 05/08/96 - changes for 3gl callbacks + skotsovo 05/01/96 - in orllasg, no need to alloc orlbl* + skrishna 04/21/96 - merge changes from 960418 object branch into big + skrishna 04/17/96 - rename orlrcpy to orlrasg + skrishna 04/12/96 - add orlr2h and orlrh2r functions + skotsovo 04/15/96 - add fnt to make the lob locator current + skrishna 04/08/96 - change orl*() to take ocienvh* and ocierrh* instead + of oroenv* + skotsovo 03/22/96 - add locator functions + skotsovo 03/22/96 - add locator functions + skrishna 02/27/96 - remove mlslabel interface + skotsovo 02/20/96 - remove orlbty and use dty type instead. + skotsovo 02/14/96 - add text file lobs. + skrishna 01/31/96 - update comments of orln2r, orldchk, orlds2d & orld2s + skrishna 01/31/96 - change orld2s() and orln2s() to return string length + skrishna 01/21/96 - remove old raw interface + skrishna 12/14/95 - add raw interface + skotsovo 01/03/96 - change LOB offsets and lengths from ub4 to ubig_ora + to support 64 bit machines. + skotsovo 10/30/95 - add orlblsiz() to get lob locator size + skrishna 10/24/95 - move ref functions from ori and update the ref + functions to support variable-length ref + cxcheng 10/20/95 - add more comments on number versions + cxcheng 10/13/95 - add more number functions + cxcheng 08/29/95 - Support for segmented varrays + cxcheng 08/18/95 - modifiy orlmls structure + skrishna 06/06/95 - rename orln, orld, orlvs and orlva to orlnum, + orldat, orlvstr and orlvary respectively + skrishna 11/15/94 - remove orlnget() function + skrishna 09/20/94 - modify orldbtw() to return number of days only + skrishna 08/24/94 - change format string length type from ub4 to ub1 + skrishna 07/19/94 - Rename orln2c & orlnc2n to orln2s & orlns2n + skrishna 06/29/94 - Add blob interface; add examples + skrishna 06/23/94 - Update comments and format + skrishna 05/19/94 - update varray append comments + skrishna 05/05/94 - Subsetting + skrishna 11/24/93 - Creation +*/ + +#ifndef ORATYPES +#include +#endif + +#ifndef ORO_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#include +#endif + +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORL_ORACLE +#define ORL_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCIArray orlvary +#define OCIColl orlcol +#define OCICollAppend orlcapp +#define OCICollAssign orlcasg +#define OCICollAssignElem orlcase +#define OCICollGetElem orlcget +#define OCICollGetElemArray orlcgeta +#define OCICollMax orlcmax +#define OCICollSize orlcsiz +#define OCICollTrim orlctrm +#define OCICollIsLocator orlcilc +#define OCIDate orldat +#define OCIDateAddDays orldadd +#define OCIDateAddMonths orldadm +#define OCIDateCheck orldchk +#define OCIDateCompare orldcmp +#define OCIDateDD day_orldat +#define OCIDateDaysBetween orldbtw +#define OCIDateFromText orlds2d +#define OCIDateLastDay orldlst +#define OCIDateMM mon_orldat +#define OCIDateNextDay orldndy +#define OCIDateSysDate orldsys +#define OCIDateTime time_orldat +#define OCIDateYYYY gye_orldat +#define OCIDateZoneToZone orldz2z +#define OCIIter orlcitr +#define OCIIterCreate orlccit +#define OCIIterDelete orlcdit +#define OCIIterGetCurrent orlcicur +#define OCIIterInit orlciit +#define OCIIterNext orlcinxt +#define OCIIterPrev orlciprv +#define OCINumber orlnum +#define OCINumberAbs orlnabs +#define OCINumberAdd orlnadd +#define OCINumberArcCos orlnacos +#define OCINumberArcSin orlnasin +#define OCINumberArcTan orlnatan +#define OCINumberAssign orlnasg +#define OCINumberCeil orlncel +#define OCINumberCos orlncos +#define OCINumberDiv orlndiv +#define OCINumberPower orlnbex +#define OCINumberFloor orlnflr +#define OCINumberFromInt orlni2n +#define OCINumberFromReal orlnr2n +#define OCINumberFromText orlns2n +#define OCINumberHypCos orlncsh +#define OCINumberHypSin orlnsnh +#define OCINumberSetZero orlnini +#define OCINumberSetPi orlnspi +#define OCINumberInc orlninc +#define OCINumberDec orlndec +#define OCINumberIntPower orlnpwr +#define OCINumberLn orlnln +#define OCINumberLog orlnlog +#define OCINumberMod orlnmod +#define OCINumberMul orlnmul +#define OCINumberNeg orlnneg +#define OCINumberPart orlnpart +#define OCINumberExp orlnexp +#define OCINumberRound orlnrou +#define OCINumberPrec orlnpre +#define OCINumberShift orlnsft +#define OCINumberSign orlnsgn +#define OCINumberSin orlnsin +#define OCINumberSqrt orlnsqr +#define OCINumberSub orlnsub +#define OCINumberTan orlntan +#define OCINumberHypTan orlntnh +#define OCINumberArcTan2 orlnatn2 +#define OCINumberToInt orln2i +#define OCINumberToReal orln2r +#define OCINumberToRealArray orln2ra +#define OCINumberToText orln2s +#define OCINumberTrunc orlntru +#define OCINumberCmp orlncmp +#define OCINumberIsZero orlnzer +#define OCINumberIsInt orlnint +#define OCIRaw orlraw +#define OCIRawAllocSize orlwasz +#define OCIRawAssignBytes orlwabr +#define OCIRawAssignRaw orlwarr +#define OCIRawPtr orlwgrp +#define OCIRawResize orlwrsz +#define OCIRawSize orlwgsz +#define OCIRefAssign orlrasg +#define OCIRefClear orlrclr +#define OCIRefFromHex orlrh2r +#define OCIRefHexSize orlrhsz +#define OCIRefIsEqual orlrequ +#define OCIRefIsNull orlrnul +#define OCIRefToHex orlr2h +#define OCIString orlvstr +#define OCIStringAllocSize orlvasz +#define OCIStringAssign orlvass +#define OCIStringAssignText orlvats +#define OCIStringPtr orlvgsp +#define OCIStringResize orlvrsz +#define OCIStringSize orlvgsz +#define OCITable orltbl +#define OCITableDelete orltdel +#define OCITableExists orltexi +#define OCITableFirst orltfst +#define OCITableLast orltlst +#define OCITableNext orltnxt +#define OCITablePrev orltprv +#define OCITableSize orltsiz +#define OCITime orldtm +#define OCITimeHH orldtmhh +#define OCITimeMI orldtmmm +#define OCITimeSS orldtmss +#define OCI_LOBMODE_READONLY ORLBMORO +#define OCI_LOBMODE_READWRITE ORLBMORW + +#endif /* SLSHORTNAME */ + +/*****************************************************************************/ +/* NUMBER/FLOAT/DECIMAL TYPE */ +/*****************************************************************************/ + +#define OCI_NUMBER_SIZE 22 +struct OCINumber +{ + ub1 OCINumberPart[OCI_NUMBER_SIZE]; +}; +typedef struct OCINumber OCINumber; + +/* + * OCINumber - OCI Number mapping in c + * + * The OTS types: NUMBER, NUMERIC, INT, SHORTINT, REAL, DOUBLE PRECISION, + * FLOAT and DECIMAL are represented by OCINumber. + * The contents of OCINumber is opaque to clients. + * + * For binding variables of type OCINumber in OCI calls (OCIBindByName(), + * OCIBindByPos(), and OCIDefineByPos()) use the type code SQLT_VNU. + */ + +/* + EXAMPLE + + The following example shows how to manipulate an attribute of type + oracle number. + + struct person + { + OCINumber sal; + }; + typedef struct person person; + + OCIError *err; + person* joe; + person* tom; + person* debbie; + OCINumber *joesal; + OCINumber *tomsal; + OCINumber *debsal; + sword status; + int inum; + double dnum; + OCINumber ornum; + char buffer[21]; + ub4 buflen; + sword result; + + /o See oci.h for an example of how to initialize OCIError. + o For this example, assume the OCIEnv and OCIError has been + o initialized. + o/ + + /o Pin joe, tom and debbie person objects in the object cache. See ori.h + o for an example on pinning objects. For this example, assume that + o joe, tom and debbie are pointing to pinned objects. + o/ + joesal = &joe->sal; + tomsal = &tom->sal; + debsal = &debbie->sal; + + /o initialize joe's salary to be $12,000 o/ + inum = 12000; + status = OCINumberFromInt(err, &inum, sizeof(inum), OCI_NUMBER_SIGNED, + joesal); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromInt o/; + + /o initialize tom's salary to be same as joe o/ + OCINumberAssign(err, joesal, tomsal); + + /o initialize debbie's salary to be 20% more than joe's o/ + dnum = 1.2; + status = OCINumberFromReal(err, &dnum, sizeof(double), &ornum); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromReal o/; + status = OCINumberMul(err, joesal, &ornum, debsal); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberMul o/; + + /o give tom a 50% raise o/ + dnum = 1.5; + status = OCINumberFromReal(err, &dnum, sizeof(double), &ornum); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromReal o/; + status = OCINumberMul(err, tomsal, &ornum, tomsal); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberMul o/; + + /o double joe's salary o/ + status = OCINumberAdd(err, joesal, joesal, joesal); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberAdd o/; + + /o get joe's salary in integer o/ + status = OCINumberToInt(err, joesal, sizeof(inum), OCI_NUMBER_SIGNED, + &inum); + if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToInt o/; + /o inum is set to 24000 o/ + + /o get debbie's salary in double o/ + status = OCINumberToReal(err, debsal, sizeof(dnum), &dnum); + if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToReal o/; + /o dnum is set to 14400 o/ + + /o print tom's salary as DEM0001`8000.00 o/ + buflen = sizeof(buffer); + status = OCINumberToText(err, tomsal, "C0999G9999D99", 13, + "NLS_NUMERIC_CHARACTERS='.`' NLS_ISO_CURRENCY='Germany'", 54, + &buflen, buffer); + if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToText o/; + printf("tom's salary = %s\n", buffer); + + /o compare joe and tom's salary o/ + status = OCINumberCmp(err, joesal, tomsal, &result); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberCmp o/; + /o result is positive o/ + + /o read debbie's new salary from string o/ + status = OCINumberFromText(err, "48`000.00", 9, "99G999D99", 9, + "NLS_NUMERIC_CHARACTERS='.`'", 27, debsal); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromText o/; + /o debbie's salary is now 48000.00 o/ + +*/ + +/*----------------------------- OCINumberInc --------------------------------*/ + +sword OCINumberInc( OCIError *err, OCINumber *number ); +/* + NAME: OCINumberInc - OCINumber INCrement numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN/OUT) a positive Oracle number to be incremented + DESCRIPTION: + Increment Oracle number in place. It is assumed that the input is + an integer between 0 and 100^21-2. If the is input too large, it will + be treated as 0 - the result will be an Oracle number 1. If the input + is not a positive integer, the result will be unpredictable. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberDec --------------------------------*/ + +sword OCINumberDec( OCIError *err, OCINumber *number ); +/* + NAME: OCINumberDec - OCINumber DECrement numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN/OUT) - a positive Oracle number to be decremented + DESCRIPTION: + Decrement Oracle number in place. It is assumed that the input is an + integer between 1 and 100^21-2. If the input is too large, it will be + treated as 1 - the result will be an Oracle number 0. If the input is + not a positive integer, the result will be unpredictable. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberSetZero -------------------------------*/ + +void OCINumberSetZero( OCIError *err, OCINumber *num ); +/* + NAME: OCINumberSetZero - OCINumber Set number to Zero value + PARAMETERS: + err (IN/OUT) - pointer to OCI error handle + num (OUT) - set to zero value + DESCRIPTION: + Initialize the given number to value 0. + */ + +/*--------------------------- OCINumberSetPi --------------------------------*/ + +void OCINumberSetPi( OCIError *err, OCINumber *num ); +/* + NAME: OCINumberSetPi - OCINumber Set number to Pi + err (IN/OUT) - pointer to OCI error handle + num (OUT) - set to zero value + DESCRIPTION: + Initialize the given number to value Pi. + */ + +/*----------------------------- OCINumberAdd --------------------------------*/ + +sword OCINumberAdd( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberAdd - OCINumber ADD numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - numbers to be added + result (OUT) - result of adding 'number1' with 'number2' + DESCRIPTION: + Add 'number1' with 'number2' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberSub --------------------------------*/ + +sword OCINumberSub( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberSub - OCINumber SUBtract numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - 'number2' subtracted from 'number1' + result (OUT) - subtraction result + DESCRIPTION: + Subtract 'number2' from 'number1' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberMul --------------------------------*/ + +sword OCINumberMul( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberMul - OCINumber MULtiply numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - numbers to be multiplied + result (OUT) - multiplication result + DESCRIPTION: + Multiply 'number1' with 'number2' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberDiv --------------------------------*/ + +sword OCINumberDiv( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberDiv - OCINumber DIVide numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1 (IN) - pointer to the numerator + number2 (IN) - pointer to the denominator + result (OUT) - division result + DESCRIPTION: + Divide 'number1' by 'number2' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + underflow errorr + overflow errorr + divide by zero errorr + */ + +/*----------------------------- OCINumberMod --------------------------------*/ + +sword OCINumberMod( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberMod - OCINumber MODulous + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1 (IN) - pointer to the numerator + number2 (IN) - pointer to the denominator + result (OUT) - remainder of the result + DESCRIPTION: + Finds the remainder of the division of two Oracle numbers. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + divide by zero errorr + */ + +/*------------------------ OCINumberIntPower --------------------------------*/ + +sword OCINumberIntPower( OCIError *err, const OCINumber *base, + const sword exp, OCINumber *result ); +/* + NAME: OCINumberIntPower - OCINumber takes an arbitary base to an arbitary + integer PoWeR + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + base (IN) - base of the exponentiation + exp (IN) - exponent to which the base is to be raised + result (OUT) - output of exponentiation + DESCRIPTION: + Takes an arbitary base to an arbitary integer power. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberShift ---------------------------------*/ + +sword OCINumberShift( OCIError *err, const OCINumber *number, + const sword nDig, OCINumber *result ); +/* + NAME: OCINumberShift - OCINumber multiplies by a power of 10. + + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - Oracle Number to be shifted. + nDig (IN) - number of decimal places to shift. + result (OUT) - shift result. + DESCRIPTION: + Multiplies number by 10^NDig and sets product to the result. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberNeg --------------------------------*/ + +sword OCINumberNeg( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberNeg - OCINumber NEGate number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be negated + result (OUT) - will contain negated value of 'number' + DESCRIPTION: + Negates an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*------------------------- OCINumberToText ---------------------------------*/ + +sword OCINumberToText( OCIError *err, const OCINumber *number, + const oratext *fmt, ub4 fmt_length, + const oratext *nls_params, ub4 nls_p_length, + ub4 *buf_size, oratext *buf ); +/* + NAME: OCINumberToText - OCINumber convert number TO String + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - Oracle number to be converted + fmt (IN) - conversion format + fmt_length (IN) - length of the 'fmt' parameter + nls_params (IN) - nls format specification, if null string + i.e. (oratext *)0, then the default parameters for the + session is used + nls_p_length (IN) - length of the 'nls_params' parameter + buf_size (IN/OUT) - size of the buffer must be passed as input by + the caller, this function will return the length of the + resulting string in bytes via this parameter. The length + does not include the terminating null ('\0'). + buf (OUT) - buffer into which the converted string is placed. The + resulting string is null terminated. + DESCRIPTION: + Converts the given number to a character string + according to the specified format. Refer to "TO_NUMBER" conversion + function described in "Oracle SQL Language Reference Manual" for a + description of format and NLS parameters. + The converted number string is stored in the buffer 'buf', up to + a max of '*buf_size' bytes. Length of the resulting string is + returned via 'buf_size'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'buf' is null + buffer too small + invalid format + invalid nls format + number to text translation for the given format causes overflow + */ + +/*-------------------------- OCINumberFromText ------------------------------*/ + +sword OCINumberFromText( OCIError *err, const oratext *str, + ub4 str_length, const oratext *fmt, ub4 fmt_length, + const oratext *nls_params, ub4 nls_p_length, + OCINumber *number ); +/* + NAME: OCINumberFromText - OCINumber convert String TO Number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + str (IN) - input string to be converted to Oracle number + str_length (IN) - size of the input string + fmt (IN) - conversion format + fmt_length (IN) - length of the 'fmt' parameter + nls_params (IN) - nls format specification, if null string + i.e. (oratext *)0, then the default parameters for the + session is used + nls_p_length (IN) - length of the 'nls_params' parameter + number (OUT) - given string converted to number + DESCRIPTION: + Converts the given string to a number + according to the specified format. Refer to "TO_NUMBER" conversion + function described in "Oracle SQL Language Reference Manual" for a + description of format and NLS parameters. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'str' is null + 'str_length' is 0 + invalid format + invalid nls format + invalid input string + */ + +/*-------------------------- OCINumberToInt ---------------------------------*/ + +#define OCI_NUMBER_UNSIGNED 0 /* Unsigned type -- ubX */ +#define OCI_NUMBER_SIGNED 2 /* Signed type -- sbX */ + +sword OCINumberToInt( OCIError *err, const OCINumber *number, + uword rsl_length, uword rsl_flag, void *rsl ); +/* + NAME: OCINumberToInt - OCINumber convert number TO Integer + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be converted + rsl_length (IN) - size of the desired result + rsl_s_flag (IN) - flag denoting the desired sign of the output; valid + values are OCI_NUMBER_UNSIGNED, OCI_NUMBER_SIGNED + rsl (OUT) - pointer to space for the result + DESCRIPTION: + Native type conversion function. + Converts the given Oracle number into an xbx (e.g. ub2, ub4, sb2 etc.) + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rsl' is null + integer value of 'number' is too big -- overflow + integer value of 'number' is too small -- underflow + invalid sign flag value ('rsl_s_flag') + */ + +/*--------------------------- OCINumberFromInt ------------------------------*/ + +sword OCINumberFromInt( OCIError *err, const void *inum, uword inum_length, + uword inum_s_flag, OCINumber *number ); +/* + NAME: OCINumberFromInt - OCINumber convert Integer TO Number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inum (IN) - pointer to the integer to be converted + inum_length (IN) - size of the integer + inum_s_flag (IN) - flag that designates the sign of the integer; valid + values are OCI_NUMBER_UNSIGNED, OCI_NUMBER_SIGNED + number (OUT) - given integer converted to Oracle number + DESCRIPTION: + Native type conversion function. Converts any Oracle standard + machine-native integer type (xbx) to an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'inum' is null + integer too BIG -- the number is too large to fit into an Oracle + number + invalid sign flag value ('inum_s_flag') + */ + +/*------------------------- OCINumberToReal ---------------------------------*/ + +sword OCINumberToReal( OCIError *err, const OCINumber *number, + uword rsl_length, void *rsl ); +/* + NAME: OCINumberToReal - OCINumber convert number TO Real + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be converted + rsl_length (IN) - is the size of the desired result, + sizeof( float | double | long double) + rsl (OUT) - pointer to space for storing the result + DESCRIPTION: + Native type conversion function. Converts an Oracle number into a + machine-native real type. This function only converts numbers up to + LDBL_DIG, DBL_DIG, or FLT_DIG digits of precision and removes + trailing zeroes. The above constants are defined in float.h + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rsl' is null + 'rsl_length' is 0 + */ + +/*------------------------- OCINumberToRealArray ----------------------------*/ + +sword OCINumberToRealArray( OCIError *err, const OCINumber **number, + uword elems, uword rsl_length, void *rsl ); +/* + NAME: OCINumberToRealArray - OCINumber convert array of numbers TO Real + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - Pointer to array of number to be converted + elems (IN) - Upper bound of number array + rsl_length (IN) - is the size of the desired result, + sizeof( float | double | long double) + rsl (OUT) - pointer to array of space for storing the result + DESCRIPTION: + Native type conversion function. Converts an Oracle number into a + machine-native real type. This function only converts numbers up to + LDBL_DIG, DBL_DIG, or FLT_DIG digits of precision and removes + trailing zeroes. The above constants are defined in float.h + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rsl' is null + 'rsl_length' is 0 + */ + +/*-------------------------- OCINumberFromReal ------------------------------*/ + +sword OCINumberFromReal( OCIError *err, const void *rnum, + uword rnum_length, OCINumber *number ); +/* + NAME: OCINumberFromReal - OCINumber convert Real TO Number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rnum (IN) - pointer to the floating point number to be converted + rnum_length (IN) - size of the desired result, i.e. + sizeof({float | double | long double}) + number (OUT) - given float converted to Oracle number + DESCRIPTION: + Native type conversion function. Converts a machine-native floating + point type to an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rnum' is null + 'rnum_length' is 0 + */ + +/*----------------------------- OCINumberCmp --------------------------------*/ + +sword OCINumberCmp( OCIError *err, const OCINumber *number1, + const OCINumber *number2, sword *result ); +/* + NAME: OCINumberCmp - OCINumber CoMPare numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - numbers to be compared + result (OUT) - 0 if equal, negative if number1 < number2, + positive if number1 > number2 + DESCRIPTION: + The function OCINumberCmp compares two numbers. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number1' or 'number2' or 'result' is null + */ + +/*---------------------------- OCINumberSign --------------------------------*/ + +sword OCINumberSign( OCIError *err, const OCINumber *number, + sword *result ); +/* + NAME: OCINumberSign - OCINumber obtains SiGN of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number whose sign is returned + result (OUT) - 0 if number == 0, -1 if number < 0, + 1 if number > 0 + DESCRIPTION: + Obtains sign of an Oracle number + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'result' is null + */ + +/*---------------------------- OCINumberIsZero ------------------------------*/ + +sword OCINumberIsZero( OCIError *err, const OCINumber *number, + boolean *result ); +/* + NAME: OCINumberIsZero - OCINumber comparison with ZERo + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - numbers to be compared + result (OUT) - set to TRUE if equal to zero else FALSE + DESCRIPTION: + Test if the given number is equal to zero. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'result' is null + */ + +/*---------------------------- OCINumberIsInt -------------------------------*/ + +sword OCINumberIsInt( OCIError *err, const OCINumber *number, + boolean *result ); +/* + NAME: OCINumberIsInt - OCINumber Is Integer value. + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be tested + result (OUT) - set to TRUE if integer value else FALSE + DESCRIPTION: + Test if the given number is an integer value. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'result' is null + */ + +/*-------------------------- OCINumberAssign --------------------------------*/ + +sword OCINumberAssign( OCIError *err, const OCINumber *from, + OCINumber *to ); +/* + NAME: OCINumberAssign - OCINumber ASsiGn number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + from (IN) - number to be assigned + to (OUT) - number copied into + DESCRIPTION: + Assign number 'from' to 'to'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'from' or 'to' is null + */ + +/*----------------------------- OCINumberAbs --------------------------------*/ + +sword OCINumberAbs( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberAbs - OCINumber compute ABSolute value + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the absolue value of the + input number + DESCRIPTION: + Computes the absolute value of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*---------------------------- OCINumberCeil --------------------------------*/ + +sword OCINumberCeil( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberCeil - OCINumber compute the CEiL value of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the ceil value of the + input number + DESCRIPTION: + Computes the ceil value of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*--------------------------- OCINumberFloor --------------------------------*/ + +sword OCINumberFloor( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberFloor - OCINumber compute the FLooR value of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the floor value of the + input number + DESCRIPTION: + Computes the floor value of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberSqrt -------------------------------*/ + +sword OCINumberSqrt( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberSqrt - OCINumber compute the SQuare Root of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the square root of the + input number + DESCRIPTION: + Computes the square root of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is negative + */ + +/*--------------------------- OCINumberTrunc --------------------------------*/ + +sword OCINumberTrunc( OCIError *err, const OCINumber *number, + sword decplace, OCINumber *result ); +/* + NAME: OCINumberTrunc - OCINumber TRUncate an Oracle number at a + specified decimal place + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + decplace (IN) - number of decimal digits to the right of the + decimal point to truncate at. Negative values are allowed. + result (OUT) - output of truncation + DESCRIPTION: + Truncate an Oracle number at a specified decimal place + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberPower ------------------------------*/ + +sword OCINumberPower( OCIError *err, const OCINumber *base, + const OCINumber *number, OCINumber *result ); +/* + NAME: OCINumberPower - OCINumber takes an arbitary Base to an + arbitary Power + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + base (IN) - base of the exponentiation + number (IN) - exponent to which the base is to be raised + result (OUT) - output of exponentiation + DESCRIPTION: + Takes an arbitary base to an arbitary power. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*--------------------------- OCINumberRound --------------------------------*/ + +sword OCINumberRound( OCIError *err, const OCINumber *number, + sword decplace, OCINumber *result ); +/* + NAME: OCINumberRound - OCINumber ROUnds an Oracle number to a specified + decimal place + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - round this number and return result in 'result' + decplace (IN) - number of decimal digits to the right of the + decimal point to round to. Negative values are allowed. + result (OUT) - output of rounding + DESCRIPTION: + Rounds an Oracle number to a specified decimal place + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*--------------------------- OCINumberPrec ---------------------------------*/ + +sword OCINumberPrec( OCIError *err, const OCINumber *number, + sword nDigs, OCINumber *result ); +/* + NAME: OCINumberPrec - Rounds an Oracle number to a specified number of + decimal digits. + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number for which to set precision. + nDig (IN) - number of decimal digits desired in the result. + result (OUT) - result. + DESCRIPTION: + Performs a floating point round with respect to the number + of digits. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberSin --------------------------------*/ + +sword OCINumberSin( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberSin - OCINumber takes the SINe of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the sine in radians + result (OUT) - result of the sine + DESCRIPTION: + Takes the sine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberArcSin --------------------------------*/ + +sword OCINumberArcSin( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberArcSin - OCINumber takes the Arc SINe of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the arc sine + result (OUT) - result of the arc sine in radians + DESCRIPTION: + Takes the arc sine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is < -1 or 'number' is > 1. + */ + +/*-------------------------- OCINumberHypSin --------------------------------*/ + +sword OCINumberHypSin( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberHypSin - OCINumber takes the SiNe Hyperbolic of an + Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the sine hyperbolic + result (OUT) - result of the sine hyperbolic + DESCRIPTION: + Takes the hyperbolic sine of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + NOTES: + An Oracle number overflow causes an unpredictable result value. + */ + +/*----------------------------- OCINumberCos --------------------------------*/ + +sword OCINumberCos( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberCos - OCINumber takes the COSine of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the cosine in radians + result (OUT) - result of the cosine + DESCRIPTION: + Takes the cosine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberArcCos --------------------------------*/ + +sword OCINumberArcCos( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberArcCos - OCINumber takes the Arc COSine of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the arc cosine + result (OUT) - result of the arc cosine in radians + DESCRIPTION: + Takes the arc cosine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is < -1 or 'number' is > 1. + */ + +/*-------------------------- OCINumberHypCos --------------------------------*/ + +sword OCINumberHypCos( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberHypCos - OCINumber takes the CoSine Hyperbolic of an + Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the cosine hyperbolic + result (OUT) - result of the cosine hyperbolic + DESCRIPTION: + Takes the hyperbolic cosine of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + NOTES: + An Oracle number overflow causes an unpredictable result value. + */ + +/*----------------------------- OCINumberTan --------------------------------*/ + +sword OCINumberTan( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberTan - OCINumber takes the TANgent of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the tangent in radians + result (OUT) - result of the tangent + DESCRIPTION: + Takes the tangent in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberArcTan --------------------------------*/ + +sword OCINumberArcTan( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberArcTan - OCINumber takes the Arc TANgent of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the arc tangent + result (OUT) - result of the arc tangent in radians + DESCRIPTION: + Takes the arc tangent in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*------------------------ OCINumberArcTan2 ---------------------------------*/ + +sword OCINumberArcTan2( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberArcTan2 - OCINumber takes the ATan2 of 2 Oracle numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1 (IN) - first argument of atan2(y,x) function which + corresponds to 'y' parameter in the function + number2 (IN) - second argument of atan2(y,x) function which + corresponds to 'x' parameter in the function + result (OUT) - result of the atan2() in radians + DESCRIPTION: + Takes the atan2(number1, number2). + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number2' is 0 + */ + +/*----------------------------- OCINumberHypTan -----------------------------*/ + +sword OCINumberHypTan( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberHypTan - OCINumber takes the TaNgent Hyperbolic of an Oracle + number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the tangent hyperbolic + result (OUT) - result of the tangent hyperbolic + DESCRIPTION: + Takes the hyperbolic tangent of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + NOTES: + An Oracle number overflow causes an unpredictable result value. + */ + +/*--------------------------- OCINumberExp ----------------------------------*/ + +sword OCINumberExp( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberExp - OCINumber EXPonential + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - e raised to this Oracle number power + result (OUT) - output of exponentiation + DESCRIPTION: + Raises e to the specified Oracle number power + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberLn ---------------------------------*/ + +sword OCINumberLn( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberLn - OCINumber Logarithm Natural + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - logarithm of this number is computed + result (OUT) - logarithm result + DESCRIPTION: + Takes the logarithm of the given Oracle number with respect + to the given base. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is <= 0 + */ + +/*----------------------------- OCINumberLog --------------------------------*/ + +sword OCINumberLog( OCIError *err, const OCINumber *base, + const OCINumber *number, OCINumber *result ); +/* + NAME: OCINumberLog - OCINumber LOGarithm any base + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + base (IN) - base of the logarithm + number (IN) - opearnd + result (OUT) - logarithm result + DESCRIPTION: + Takes the logarithm with the specified base of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is <= 0 + 'base' is <= 0 + */ + +/*****************************************************************************/ +/* ORACLE DATE TYPE */ +/*****************************************************************************/ + +struct OCITime +{ + ub1 OCITimeHH; /* hours; range is 0 <= hours <=23 */ + ub1 OCITimeMI; /* minutes; range is 0 <= minutes <= 59 */ + ub1 OCITimeSS; /* seconds; range is 0 <= seconds <= 59 */ +}; +typedef struct OCITime OCITime; + +/* + * OCITime - OCI TiMe portion of date + * + * This structure should be treated as an opaque structure as the format + * of this structure may change. Use OCIDateGetTime/OCIDateSetTime + * to manipulate time portion of OCIDate. + */ + +struct OCIDate +{ + sb2 OCIDateYYYY; /* gregorian year; range is -4712 <= year <= 9999 */ + ub1 OCIDateMM; /* month; range is 1 <= month < 12 */ + ub1 OCIDateDD; /* day; range is 1 <= day <= 31 */ + OCITime OCIDateTime; /* time */ +}; +typedef struct OCIDate OCIDate; + +/* + * OCIDate - OCI oracle Date representation in C + * + * OCIDate represents the C mapping of Oracle date. + * + * This structure should be treated as an opaque structure as the format + * of this structure may change. Use OCIDateGetDate/OCIDateSetDate + * to access/initialize OCIDate. + * + * For binding variables of type OCIDate in OCI calls (OCIBindByName(), + * OCIBindByPos(), and OCIDefineByPos()) use the type code SQLT_ODT. + */ + +/* + EXAMPLE + + The following example shows how to manipulate an attribute of type + oracle date. + + #define FMT "Month dd, YYYY, HH:MI A.M." + #define LANG "American" + + struct person + { + OCIDate start_date; + }; + typedef struct person person; + + OCIError *err; + person *joe; + sword status; /o error status o/ + + /o See oci.h for an example of how to initialize OCIError. + o For this example, assume the OCIEnv and OCIError has been + o initialized. + o/ + + /o Pin joe person object in the object cache. See ori.h + o for an example on pinning objects. For this example, assume that + o joe is pointing to the pinned object. + o/ + + /o set the start date of joe o/ + OCIDateSetTime(&joe->start_date, 8, 0, 0); + OCIDateSetDate(&joe->start_date, 1990, 10, 5); + + /o check if the date is valid o/ + uword invalid; + if (OCIDateCheck(err, &joe->start_date, &invalid) != OCI_SUCCESS) + /o error handling code o/ + if (invalid) + /o error handling code o/ + + /o convert date for display purposes o/ + char str[100]; + ub4 strlen = sizeof(str); + if (OCIDateToText(err, &joe->start_date, FMT, sizeof(FMT)-1, LANG, + sizeof(LANG)-1, &strlen, str) != OCI_SUCCESS) + /o error handling code o/ + + */ + +/*--------------------------- OCIDateGetTime --------------------------------*/ +/* void OCIDateGetTime(/o_ const OCIDate *date, ub1 *hour, ub1 *min, + ub1 *sec _o/); */ +#define OCIDateGetTime(date, hour, min, sec) \ + { \ + *hour = (date)->OCIDateTime.OCITimeHH; \ + *min = (date)->OCIDateTime.OCITimeMI; \ + *sec = (date)->OCIDateTime.OCITimeSS; \ + } +/* + NAME: OCIDateGetTime - OCIDate Get Time portion of date + PARAMETERS: + date (IN) - Oracle date whose time data is retrieved + hour (OUT) - hour value returned + min (OUT) - minute value returned + sec (OUT) - second value returned + DESCRIPTION: + Return time inforamtion stored in the given date. The time + information returned is: hour, minute and seconds. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateGetDate --------------------------------*/ +/* void OCIDateGetDate(/o_ const OCIDate *date, sb2 *year, ub1 *month, + ub1 *day _o/); */ +#define OCIDateGetDate(date, year, month, day) \ + { \ + *year = (date)->OCIDateYYYY; \ + *month = (date)->OCIDateMM; \ + *day = (date)->OCIDateDD; \ + } +/* + NAME: OCIDateGetDate - OCIDate Get Date (year, month, day) portion of date + PARAMETERS: + date (IN) - Oracle date whose year, month, day data is retrieved + year (OUT) - year value returned + month (OUT) - month value returned + day (OUT) - day value returned + DESCRIPTION: + Return year, month, day inforamtion stored in the given date. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateSetTime --------------------------------*/ +/* void OCIDateSetTime(/o_ OCIDate *date, ub1 hour, ub1 min, + ub1 sec _o/); */ +#define OCIDateSetTime(date, hour, min, sec) \ + { \ + (date)->OCIDateTime.OCITimeHH = hour; \ + (date)->OCIDateTime.OCITimeMI = min; \ + (date)->OCIDateTime.OCITimeSS = sec; \ + } +/* + NAME: OCIDateSetTime - OCIDate Set Time portion of date + PARAMETERS: + date (OUT) - Oracle date whose time data is set + hour (IN) - hour value to be set + min (IN) - minute value to be set + sec (IN) - second value to be set + DESCRIPTION: + Set the date with the given time inforamtion. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateSetDate --------------------------------*/ +/* void OCIDateSetDate(/o_ OCIDate *date, sb2 year, ub1 month, ub1 day _o/); */ +#define OCIDateSetDate(date, year, month, day) \ + { \ + (date)->OCIDateYYYY = year; \ + (date)->OCIDateMM = month; \ + (date)->OCIDateDD = day; \ + } +/* + NAME: OCIDateSetDate - OCIDate Set Date (year, month, day) portion of date + PARAMETERS: + date (IN) - Oracle date whose year, month, day data is set + year (OUT) - year value to be set + month (OUT) - month value to be set + day (OUT) - day value to be set + DESCRIPTION: + Set the date with the given year, month, day inforamtion. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateAssign ---------------------------------*/ + +sword OCIDateAssign( OCIError *err, const OCIDate *from, + OCIDate *to ); +/* + NAME: OCIDateAssign - OCIDate Assignment + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + from (IN) - date to be assigned + to (OUT) - lhs of assignment + DESCRIPTION: + Performs date assignment. + RETURNS: + OCI_SUCCESS + */ + +/*--------------------------- OCIDateToText ---------------------------------*/ + +sword OCIDateToText( OCIError *err, const OCIDate *date, + const oratext *fmt, ub1 fmt_length, + const oratext *lang_name, ub4 lang_length, + ub4 *buf_size, oratext *buf ); +/* + NAME: OCIDateToText - OCIDate convert date TO String + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - Oracle date to be converted + fmt (IN) - conversion format, if null string pointer (oratext*)0, then + the date is converted to a character string in the + date format "DD-MON-YY". + fmt_length (IN) - length of the 'fmt' parameter + lang_name (IN) - specifies the language in which the names and + abbreviations of months and days are returned; + default language of session is used if 'lang_name' + is null i.e. (oratext *)0 + lang_length (IN) - length of the 'nls_params' parameter + buf_size (IN/OUT) - size of the buffer; size of the resulting string + is returned via this parameter + buf (OUT) - buffer into which the converted string is placed + DESCRIPTION: + Converts the given date to a string according to the specified format. + Refer to "TO_DATE" conversion function described in + "Oracle SQL Language Reference Manual" for a description of format + and NLS arguments. The converted null-terminated date string is + stored in the buffer 'buf'. + + An error is reported upon overflow, e.g. trying to convert a number + of value 10 using format '9' causes an overflow. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + invalid format + unknown language + overflow error + */ + +/*---------------------------- OCIDateFromText ------------------------------*/ + +sword OCIDateFromText( OCIError *err, const oratext *date_str, + ub4 d_str_length, const oratext *fmt, ub1 fmt_length, + const oratext *lang_name, ub4 lang_length, + OCIDate *date ); +/* + NAME: OCIDateFromText - OCIDate convert String TO Date + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date_str (IN) - input string to be converted to Oracle date + d_str_length (IN) - size of the input string, if the length is -1 + then 'date_str' is treated as a null terminated string + fmt (IN) - conversion format; if 'fmt' is a null pointer, then + the string is expected to be in 'DD-MON-YY' format. + fmt_length (IN) - length of the 'fmt' parameter + lang_name (IN) - language in which the names and abbreviations of + days and months are specified, if null i.e. (oratext *)0, + the default language of session is used, + lang_length (IN) - length of the 'lang_name' parameter + date (OUT) - given string converted to date + DESCRIPTION: + Converts the given string to Oracle date + according to the specified format. Refer to "TO_DATE" conversion + function described in "Oracle SQL Language Reference Manual" for a + description of format. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid format + unknown language + invalid input string + + */ + +/*----------------------------- OCIDateCompare ------------------------------*/ + +sword OCIDateCompare( OCIError *err, const OCIDate *date1, + const OCIDate *date2, sword *result ); +/* + NAME: OCIDateCompare - OCIDate CoMPare dates + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date1, date2 (IN) - dates to be compared + result (OUT) - comparison result, 0 if equal, -1 if date1 < date2, + 1 if date1 > date2 + DESCRIPTION: + The function OCIDateCompare compares two dates. It returns -1 if date1 + is smaller than date2, 0 if they are equal, and 1 if date1 is greater + than date2. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*------------------------- OCIDateAddMonths --------------------------------*/ + +sword OCIDateAddMonths( OCIError *err, const OCIDate *date, sb4 num_months, + OCIDate *result ); +/* + NAME: OCIDateAddMonths - OCIDate ADd or subtract Months + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - 'num_months' added or subtracted from 'date' + num_months (IN) - number of months to be added or subtracted + (a negative value will be subtracted) + result (IN/OUT) - result of adding or subtracting to 'date' + DESCRIPTION: + The function OCIDateAddDays adds or subtracts num_months from the + date 'date'. + If the input 'date' is the last day of a month, then + appropriate adjustments are made to ensure that the output date is + also the last day of the month. For example, Feb. 28 + 1 month = + March 31, and November 30 - 3 months = August 31. Otherwise the + 'result' date has the same day component as 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*--------------------------- OCIDateAddDays --------------------------------*/ + +sword OCIDateAddDays( OCIError *err, const OCIDate *date, sb4 num_days, + OCIDate *result ); +/* + NAME: OCIDateAddDays - OCIDate ADd or subtract Days + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - 'num_days' added or subtracted from 'date' + num_days (IN) - number of days to be added or subtracted + (a negative value will be subtracted) + result (IN/OUT) - result of adding or subtracting to 'date' + DESCRIPTION: + The function OCIDateAddDays adds or subtracts num_days from the + date 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*--------------------------- OCIDateLastDay --------------------------------*/ + +sword OCIDateLastDay( OCIError *err, const OCIDate *date, + OCIDate *last_day ); +/* + NAME: OCIDateLastDay - OCIDate get date of the LaST day of the month + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - input date + last_day (OUT) - last day of the month in date 'date' + DESCRIPTION: + The function OCIDateLastDay returns the date of the last day of the + month in date 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*----------------------- OCIDateDaysBetween --------------------------------*/ + +sword OCIDateDaysBetween( OCIError *err, const OCIDate *date1, + const OCIDate *date2, sb4 *num_days ); +/* + NAME: OCIDateDaysBetween - OCIDate get number of days BeTWeen two dates + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date1, date2 (IN) - input dates + num_days (OUT) - number of days between date1 and date2 + DESCRIPTION: + The function OCIDateDaysBetween returns the number of days between + date1 and date2. The time is ignored in this computation. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*------------------------ OCIDateZoneToZone --------------------------------*/ + +sword OCIDateZoneToZone( OCIError *err, const OCIDate *date1, + const oratext *zon1, + ub4 zon1_length, const oratext *zon2, + ub4 zon2_length, OCIDate *date2 ); +/* + NAME: OCIDateZoneToZone - OCIDate convert date from one Zone TO another Zone + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date1 (IN) - date to be converted + zon1 (IN) - zone of input date + zon1_length (IN) - length in bytes of string 'zon1' + zon2 (IN) - zone to be converted to + zon2_length (IN) - length in bytes of string 'zon2' + date2 (OUT) - converted date (in 'zon2') + DESCRIPTION: + Converts date from one time zone to another. Given date 'date1' + in time zone 'zon1' returns date 'date2' in time zone 'zon2'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invlid date + invald input time zone + invald output time zone + + */ + +/*--------------------------- OCIDateNextDay --------------------------------*/ + +sword OCIDateNextDay( OCIError *err, const OCIDate *date, + const oratext *day_p, ub4 day_length, + OCIDate *next_day ); +/* + NAME: OCIDateNextDay - OCIDate get date of Next DaY + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - returned date should be later than this date + day (IN) - first day of week named by this is returned + day_length (IN) - length in bytes of string 'day' + next_day (OUT) - first day of the week named by 'day' later than 'date' + DESCRIPTION: + Returns the date of the first day of the + week named by 'day' that is later than date 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + invalid day + + */ + +/*----------------------------- OCIDateCheck --------------------------------*/ + +/* Listing of error bits used by OCIDateCheck() */ +#define OCI_DATE_INVALID_DAY 0x1 /* Bad DAy */ +#define OCI_DATE_DAY_BELOW_VALID 0x2 /* Bad DAy Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_MONTH 0x4 /* Bad MOnth */ +#define OCI_DATE_MONTH_BELOW_VALID 0x8 /* Bad MOnth Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_YEAR 0x10 /* Bad YeaR */ +#define OCI_DATE_YEAR_BELOW_VALID 0x20 /* Bad YeaR Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_HOUR 0x40 /* Bad HouR */ +#define OCI_DATE_HOUR_BELOW_VALID 0x80 /* Bad HouR Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_MINUTE 0x100 /* Bad MiNute */ +#define OCI_DATE_MINUTE_BELOW_VALID 0x200 + /* Bad MiNute Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_SECOND 0x400 /* Bad SeCond */ +#define OCI_DATE_SECOND_BELOW_VALID 0x800 + /* bad second Low/high bit (1=low)*/ +#define OCI_DATE_DAY_MISSING_FROM_1582 0x1000 + /* Day is one of those "missing" from 1582 */ +#define OCI_DATE_YEAR_ZERO 0x2000 /* Year may not equal zero */ +#define OCI_DATE_INVALID_FORMAT 0x8000 /* Bad date format input */ + +sword OCIDateCheck( OCIError *err, const OCIDate *date, uword *valid ); +/* + NAME: OCIDateCheck - OCIDate CHecK if the given date is valid + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - date to be checked + valid (OUT) - returns zero for a valid date, otherwise + the ORed combination of all error bits specified below: + + Macro name Bit number Error + ---------- ---------- ----- + OCI_DATE_INVALID_DAY 0x1 Bad day + OCI_DATE_DAY_BELOW_VALID 0x2 Bad DAy Low/high bit (1=low) + OCI_DATE_INVALID_MONTH 0x4 Bad MOnth + OCI_DATE_MONTH_BELOW_VALID 0x8 Bad MOnth Low/high bit (1=low) + OCI_DATE_INVALID_YEAR 0x10 Bad YeaR + OCI_DATE_YEAR_BELOW_VALID 0x20 Bad YeaR Low/high bit (1=low) + OCI_DATE_INVALID_HOUR 0x40 Bad HouR + OCI_DATE_HOUR_BELOW_VALID 0x80 Bad HouR Low/high bit (1=low) + OCI_DATE_INVALID_MINUTE 0x100 Bad MiNute + OCI_DATE_MINUTE_BELOW_VALID 0x200 Bad MiNute Low/high bit (1=low) + OCI_DATE_INVALID_SECOND 0x400 Bad SeCond + OCI_DATE_SECOND_BELOW_VALID 0x800 bad second Low/high bit (1=low) + OCI_DATE_DAY_MISSING_FROM_1582 0x1000 Day is one of those "missing" + from 1582 + OCI_DATE_YEAR_ZERO 0x2000 Year may not equal zero + OCI_DATE_INVALID_FORMAT 0x8000 Bad date format input + + So, for example, if the date passed in was 2/0/1990 25:61:10 in + (month/day/year hours:minutes:seconds format), the erroor returned + would be OCI_DATE_INVALID_DAY | OCI_DATE_DAY_BELOW_VALID | + OCI_DATE_INVALID_HOUR | OCI_DATE_INVALID_MINUTE + + DESCRIPTION: + Check if the given date is valid. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'date' and 'valid' pointers are NULL pointers + */ + +/*--------------------------- OCIDateSysDate --------------------------------*/ + +sword OCIDateSysDate( OCIError *err, OCIDate *sys_date ); +/* + NAME: OCIDateSysDate - OCIDate get current SYStem date and time + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + sys_date (OUT) - current system date and time + DESCRIPTION: + Returns the current system date and time. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + + */ + +/*****************************************************************************/ +/* FIXED-LENGTH STRING - CHAR (N) */ +/*****************************************************************************/ + +/* + * An ADT attribute declared as "x CHAR(n)" is mapped to "OCIString *x;". + * The representation of OCIString * is shown below. + */ + +/*****************************************************************************/ +/* VARIABLE-LENGTH STRING */ +/*****************************************************************************/ + +/* + * The variable-length string is represented in C as a pointer to OCIString + * structure. The OCIString structure is opaque to the user. Functions are + * provided to allow the user to manipulate a variable-length string. + * + * A variable-length string can be declared as: + * + * OCIString *vstr; + * + * For binding variables of type OCIString* in OCI calls (OCIBindByName(), + * OCIBindByPos() and OCIDefineByPos()) use the external type code SQLT_VST. + */ +typedef struct OCIString OCIString; + +/*-------------------------- OCIStringAssign --------------------------------*/ + +sword OCIStringAssign( OCIEnv *env, OCIError *err, const OCIString *rhs, + OCIString **lhs ); +/* + NAME: OCIStringAssign - OCIString Assign String to String + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is also OCIString + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' string to 'lhs' string. The 'lhs' string may be + resized depending upon the size of the 'rhs'. The assigned string is + null-terminated. The 'length' field will not include the extra byte + needed for null termination. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*---------------------- OCIStringAssignText --------------------------------*/ + +sword OCIStringAssignText( OCIEnv *env, OCIError *err, const oratext *rhs, + ub4 rhs_len, OCIString **lhs ); +/* + NAME: OCIStringAssignText - OCIString Assign Text string to String + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is a text string + rhs_len (IN) - length of the 'rhs' string + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' string to 'lhs' string. The 'lhs' string may be + resized depending upon the size of the 'rhs'. The assigned string is + null-terminated. The 'length' field will not include the extra byte + needed for null termination. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*-------------------------- OCIStringResize --------------------------------*/ + +sword OCIStringResize( OCIEnv *env, OCIError *err, ub4 new_size, + OCIString **str ); +/* + NAME: OCIStringResize - OCIString ReSiZe string memory + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + new_size (IN) - new memory size of the string in bytes + str (IN/OUT) - allocated memory for the string is freed from the + OOCI heap + DESCRIPTION: + This function resizes the memory of the given variable-length string in + the object cache. The contents of the string are NOT preserved. + This function may allocate the string in a new memory region in + which case the original memory occupied by the given string will + be freed. If the input string is null (str == NULL), then this + function will allocate memory for the string. + + If the new_size is 0, then this function frees the memory occupied + by 'str' and a null pointer value is returned. + + NOTE: The caller must compute 'new_size' taking into account space + for the null character ('\0'). + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*---------------------------- OCIStringSize --------------------------------*/ + +ub4 OCIStringSize( OCIEnv *env, const OCIString *vs ); +/* + NAME: OCIStringSize - OCIString Get String siZe + PARAMETERS: + env(IN) - pointer to OCI environment handle + vs (IN) - string whose size is returned + DESCRIPTION: + Return the size of the given string. + RETURNS: + size of the string in bytes is returned + */ + +/*----------------------------- OCIStringPtr --------------------------------*/ + +oratext *OCIStringPtr( OCIEnv *env, const OCIString *vs ); +/* + NAME: OCIStringPtr - OCIString Get String Pointer + PARAMETERS: + env(IN) - pointer to OCI environment handle + vs (IN) - pointer to the text of this string is returned + DESCRIPTION: + Return the pointer to the text of the given string. + RETURNS: + pointer to the text of the string is returned + */ + +/*----------------------- OCIStringAllocSize --------------------------------*/ + +sword OCIStringAllocSize( OCIEnv *env, OCIError *err, const OCIString *vs, + ub4 *allocsize ); +/* + NAME: OCIStringAllocSize - OCIString get Allocated SiZe of string memory + in bytes + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + vs (IN) - string whose allocated size in bytes is returned + allocsize (OUT) - allocated size of string memory in bytes is returned + DESCRIPTION: + Return the allocated size of the string memory in bytes. The + allocated size is >= actual string size. + REQUIRES: + vs is a non-null pointer + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR on error + */ + +/*****************************************************************************/ +/* VARIABLE-LENGTH RAW */ +/*****************************************************************************/ + +/* + * The variable-length raw is represented in C as a pointer to OCIRaw + * structure. The OCIRaw structure is opaque to the user. Functions are + * provided to allow the user to manipulate a variable-length raw. + * + * A variable-length raw can be declared as: + * + * OCIRaw *raw; + * + * For binding variables of type OCIRaw* in OCI calls (OCIBindByName(), + * OCIBindByPos() and OCIDefineByPos()) use the external type code SQLT_LVB. + */ +typedef struct OCIRaw OCIRaw; + +/*-------------------------- OCIRawAssignRaw --------------------------------*/ + +sword OCIRawAssignRaw( OCIEnv *env, OCIError *err, const OCIRaw *rhs, + OCIRaw **lhs ); +/* + NAME: OCIRawAssignRaw - OCIRaw Assign Raw (of type OCIRaw*) to + Raw (of type OCIRaw*) + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is also OCIRaw + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' raw to 'lhs' raw. The 'lhs' raw may be + resized depending upon the size of the 'rhs'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*------------------------ OCIRawAssignBytes --------------------------------*/ + +sword OCIRawAssignBytes( OCIEnv *env, OCIError *err, const ub1 *rhs, + ub4 rhs_len, OCIRaw **lhs ); +/* + NAME: OCIRawAssignBytes - OCIRaw Assign raw Bytes (of type ub1*) to Raw + (of type OCIRaw*) + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is ub1 * + rhs_len (IN) - length of the 'rhs' raw + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' raw to 'lhs' raw. The 'lhs' raw may be + resized depending upon the size of the 'rhs'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*---------------------------- OCIRawResize ---------------------------------*/ + +sword OCIRawResize( OCIEnv *env, OCIError *err, ub4 new_size, + OCIRaw **raw ); +/* + NAME: OCIRawResize - OCIRaw ReSiZe memory of variable-length raw + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + new_size (IN) - new size of the raw data in bytes + raw (IN) - variable-length raw pointer; the raw is + resized to 'new_size' + DESCRIPTION: + This function resizes the memory of the given variable-length raw in + the object cache. + The previous contents of the raw are NOT preserved. + This function may allocate the raw in a new memory region in + which case the original memory occupied by the given raw will + be freed. If the input raw is null (raw == NULL), then this + function will allocate memory for the raw data. + + If the new_size is 0, then this function frees the memory occupied + by 'raw' and a null pointer value is returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*------------------------------- OCIRawSize --------------------------------*/ + +ub4 OCIRawSize( OCIEnv * env, const OCIRaw *raw ); +/* + NAME: OCIRawSize - OCIRaw Get Raw siZe + PARAMETERS: + env (IN) - pointer to OCI environment handle + raw (INT) - raw whose size is returned + DESCRIPTION: + Return the size of the given raw. + RETURNS: + size of the raw in bytes is returned + */ + +/*--------------------------------- OCIRawPtr -------------------------------*/ +ub1 *OCIRawPtr( OCIEnv * env, const OCIRaw *raw ); +/* + NAME: OCIRawPtr - OCIRaw Get Raw data Pointer + PARAMETERS: + env (IN) - pointer to OCI environment handle + raw (IN) - pointer to the data of this raw is returned + DESCRIPTION: + Return the pointer to the data of the given raw. + RETURNS: + pointer to the data of the raw is returned + */ + +/*------------------------------ OCIRawAllocSize ----------------------------*/ + +sword OCIRawAllocSize( OCIEnv *env, OCIError *err, const OCIRaw *raw, + ub4 *allocsize ); +/* + NAME: OCIRawAllocSize - OCIRaw get Allocated SiZe of raw memory in bytes + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + raw (IN) - raw whose allocated size in bytes is returned + allocsize (OUT) - allocated size of raw memory in bytes is returned + DESCRIPTION: + Return the allocated size of the raw memory in bytes. The + allocated size is >= actual raw size. + REQUIRES: + raw is a non-null pointer + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR upon error + */ + +/*****************************************************************************/ +/* OBJECT REFERENCE OPERATIONS */ +/*****************************************************************************/ + +/* + * See the definition of OCIRef in oro.h. + * + * For binding variables of type OCIRef* in OCI calls (OCIBindByName(), + * OCIBindByPos() and OCIDefineByPos()) use the code SQLT_REF. + * + */ + +/*---------------------------- OCIRefClear ----------------------------------*/ +void OCIRefClear( OCIEnv *env, OCIRef *ref ); +/* + NAME: OCIRefClear - OCIRef CLeaR or nullify a ref + PARAMETERS: + env (IN) - pointer to OCI environment handle + ref (IN/OUT) - ref to clear + DESCRIPTION: + Clear or nullify the given ref. A ref is considered to be a null ref + if it does not contain a valid OID (and thus doesn't point to an + object). Logically, a null ref is a dangling ref. + + Note that a null ref is still a valid SQL value and is not SQL-ly null. + It can be used as a valid non-null constant ref value for NOT NULL + column or attribute of a row in a table. + + If a null pointer value is passed as a ref, + then this function is a no-op. + */ + +/*--------------------------- OCIRefAssign ----------------------------------*/ +sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source, + OCIRef **target ); +/* + NAME: OCIRefAssign - OCIRef CoPY a ref to another + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + source (IN) - ref to copy from + target (IN/OUT) - ref to copy to + DESCRIPTION: + Copy 'source' ref to 'target' ref; both then reference the same + object. If the target ref pointer is null (i.e. *target == NULL) + then the copy function will allocate memory for the target ref + in OOCI heap prior to the copy. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + 1) out of memory + */ + +/*-------------------------- OCIRefIsEqual ----------------------------------*/ +boolean OCIRefIsEqual( OCIEnv *env, const OCIRef *x, const OCIRef *y ); +/* + NAME: OCIRefIsEqual - OCIRef compare two refs for EQUality + PARAMETERS: + env (IN) - pointer to OCI environment handle + x (IN) - ref to compare + y (IN) - ref to compare + DESCRIPTION: + Compare the given refs for equality. + Two refs are equal if and only if: + - they are both referencing the same persistent object, or + - they are both referencing the same transient object. + + NOTE THAT TWO NULL REFS ARE CONSIDERED NOT EQUAL BY THIS FUNCTION. + RETURNS: + TRUE if the two refs are equal + FALSE if the two refs are not equal, or X is NULL, or Y is NULL + */ + +/*--------------------------- OCIRefIsNull ----------------------------------*/ +boolean OCIRefIsNull( OCIEnv *env, const OCIRef *ref ); +/* + NAME: OCIRefIsNull - OCIRef test if a ref is NULl + PARAMETERS: + env (IN) - pointer to OCI environment handle + ref (IN) - ref to test for null + DESCRIPTION: + Return TRUE if the given ref is null; otherwise, return FALSE. + A ref is null if and only if: + - it is supposed to be referencing a persistent object, but + its OID is null, or + - it is supposed to be referencing a transient object, but it is + currently not pointing to an object. + A ref is a dangling ref if the object that it points to does not + exist. + RETURNS: + TRUE if the given ref is NULL + FALSE if the given ref is not NULL + */ + +/*-------------------------- OCIRefHexSize ----------------------------------*/ +ub4 OCIRefHexSize( OCIEnv *env, const OCIRef *ref ); +/* + NAME: OCIRefHexSize - OCIRef Hexadecimal buffer SiZe in bytes + PARAMETERS: + env (IN) - pointer to OCI environment handle + ref (IN) - ref whose size in hexadecimal representation in bytes is + returned + DESCRIPTION: + Return the size of the buffer in bytes required for the hexadecimal + representation of the ref. A buffer of at-least this size must be + passed to ref-to-hex (OCIRefToHex) conversion function. + RETURNS: + size of hexadecimal representation of ref + */ + +/*-------------------------- OCIRefFromHex ---------------------------------*/ +sword OCIRefFromHex( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + const oratext *hex, ub4 length, OCIRef **ref ); +/* + NAME: + OCIRefFromHex - OCIRef convert a Hexadecimal string TO a Ref + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + svc (IN) - OCI service context handle; if the resulting ref is + initialized with this service context + hex (IN) - hexadecimal string (that was produced by 'OCIRefToHex()" + previously) to be convert into a ref + length (IN) - length of the hexadecimal string + ref (IN/OUT) - ref is initialized with the given value ('hex'). + If *ref is null, then space for the ref is allocated in the + object cache, otherwise the memory occupied by the given ref + is re-used. + DESCRIPTION: + Convert the given hexadecimal string into a ref. This function + ensures that the resulting ref is well formed. It does NOT ensure + that the object pointed to by the resulting ref exists or not. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + */ + +/*--------------------------- OCIRefToHex -----------------------------------*/ +sword OCIRefToHex( OCIEnv *env, OCIError *err, const OCIRef *ref, + oratext *hex, ub4 *hex_length ); +/* + NAME: + OCIRefToHex - OCIRef convert ref to a Hexadecimal string + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + ref (IN) - ref to be converted into a hexadecimal string; if the + ref is a null ref (i.e. OCIRefIsNull(ref) == TRUE) then + a zero hex_length value is returned + hex (OUT) - buffer that is large enough to contain the resulting + hexadecimal string; the contents of the string is opaque + to the caller + hex_length (IN/OUT) - on input specifies the size of the 'hex' buffer, + on output specifies the actual size of the hexadecimal + string being returned in 'hex' + DESCRIPTION: + Convert the given ref into a hexadecimal string, and return the length + of the string. The resulting string is opaque to the caller. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + the given buffer is not big enough to hold the resulting string + */ + + +/*****************************************************************************/ +/* COLLECTION FUNCTIONS */ +/*****************************************************************************/ + +/* + The generic collection is represented by the type 'OCIColl'. The following + operations OCIColl*() are provided on a generic collection: + - get current size of collection + - get upper bound of collection + - get pointer to an element given its index + - set element at given index (assign element) + - append an element + - trim the given number of elements from the end of the collection + - collection assignment + + The following iterator based scanning functions are also provided on a + generic collection. These functions make use of an iterator which is + defined to be of type OCIIter. + + - create an iterator for scanning collection + - destroy iterator + - reset iterator to the beginning of collection + - get pointer to current element pointed by iterator + - get pointer to next element + - get pointer to previous element + + The collections variable-length array (varray) and nested table + are sub-types of generic collection. This means that the OCIColl*() + functions can also be used to manipulate varray and nested table. + + The varray is represented by OCIArray type and nested table by OCITable. + Besides OCIColl*() functions no additional functions are provided for + manipulating varrays. The OCIColl*() functions are a complete set of + functions to manipulate varrays. + + Besides OCIColl*() functions, the following functions OCITable*() can be + used to manipulate nested table. The OCITable*() functions operate on + nested tables only and should not be used on a varray. + + - delete an element at index i. Note that the position + ordinals of the remaining elements of the table is not changed by the + delete operation. So delete creates "holes" in the table. + - check if an element exists at the given index i + - return the smallest value of i for which exists(i) is true + - return the largest value of i for which exists(i) is true + - return pointer to the smallest position j, greater than i, such that + OCITableExists(j) is true + - return pointer to the largest position j, less than i, such that + OCITableExists(j) is true + + For binding variables of type OCIColl* or OCITable* in OCI calls + (OCIBindByName(), OCIBindByPos() and OCIDefineByPos()) use the external + type code SQLT_NTY. + */ + +/* OCIColl - generic collection type */ +typedef struct OCIColl OCIColl; + +/* OCIArray - varray collection type */ +typedef OCIColl OCIArray; + +/* OCITable - nested table collection type */ +typedef OCIColl OCITable; + +/* OCIIter - collection iterator */ +typedef struct OCIIter OCIIter; + +/*----------------------------- OCICollSize ---------------------------------*/ + +sword OCICollSize( OCIEnv *env, OCIError *err, const OCIColl *coll, + sb4 *size ); +/* + NAME: OCICollSize - OCIColl return current SIZe of the given collection + PARAMETERS: + env(IN) - pointer to OCI environment handle + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection whose number of elements is returned + size (OUT) - current number of elements in the collection + DESCRIPTION: + Returns the current number of elements in the given collection. + + For collections of type nested table wherein 'delete element' + operation is allowed, the count returned by OCICollSize() will + NOT be decremented upon deleting elements. For example: + + OCICollSize(...); + // assume 'size' returned is equal to 5 + OCITableDelete(...); // delete one element + OCICollSize(...); + // 'size' returned will still be 5 + + To get the count minus the deleted elements use OCITableSize(). + Continuing the above example, + + OCITableSize(...) + // 'size' returned will be equal to 4 + + Note, a trim operation (OCICollTrim) will decrement the count + by the number of trimmed elements. Continuing the above example, + + OCICollTrim(..,1..); // trim one element + OCICollSize(...); + // 'size' returned will be equal to 4 + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + error during loading of collection into object cache + any of the input parameters is null + */ + +/*------------------------------ OCICollMax ---------------------------------*/ + +sb4 OCICollMax( OCIEnv *env, const OCIColl *coll ); +/* + NAME: OCICollMax - OCIColl return MAXimum size (upper-bound) of the + given collection (in number of elements) + PARAMETERS: + env(IN) - pointer to OCI environment handle + coll (IN) - collection whose upper-bound in number of elements + is returned + DESCRIPTION: + Returns the max number of elements that the given collection can hold. + A value 0 indicates that the collection has no upper-bound. + REQUIRES: + coll must point to a valid collection descriptor + RETURNS: + upper-bound of the given collection + */ + +/*-------------------------- OCICollGetElem ---------------------------------*/ + +sword OCICollGetElem( OCIEnv *env, OCIError *err, const OCIColl *coll, + sb4 index, boolean *exists, void **elem, + void **elemind ); +/* + NAME: OCICollGetElem - OCIColl GET pointer to the element at the given index + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - pointer to the element in this collection is returned + index (IN) - index of the element whose pointer is returned + exists (OUT) - set to FALSE if element at the specified index does + not exist else TRUE + elem (OUT) - address of the desired element is returned + elemind (OUT) [optional] - address of the null indicator information + is returned; if (elemind == NULL) then the null indicator + information will NOT be returned + DESCRIPTION: + Get the address of the element at the given position. Optionally + this function also returns the address of the element's null indicator + information. + + The following table describes for each collection element type + what the corresponding element pointer type is. The element pointer + is returned via the 'elem' parameter of OCICollGetElem(). + + Element Type *elem is set to + ----------------------- --------------- + Oracle Number (OCINumber) OCINumber* + Date (OCIDate) OCIDate* + Variable-length string (OCIString*) OCIString** + Variable-length raw (OCIRaw*) OCIRaw** + object reference (OCIRef*) OCIRef** + lob locator (OCILobLocator*) OCILobLocator** + object type (e.g. person) person* + + The element pointer returned by OCICollGetElem() is in a form + such that it can not only be used to access the + element data but also is in a form that can be used as the target + (i.e left-hand-side) of an assignment statement. + + For example, assume the user is iterating over the elements of + a collection whose element type is object reference (OCIRef*). A call + to OCICollGetElem() returns pointer to a reference handle + (i.e. OCIRef**). After getting, the pointer to the collection + element, the user may wish to modify it by assigning a new reference. + This can be accomplished via the ref assignment function shown below: + + sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source, + OCIRef **target ); + + Note that the 'target' parameter of OCIRefAssign() is of type + 'OCIRef**'. Hence OCICollGetElem() returns 'OCIRef**'. + If '*target == NULL' a new ref will be allocated by OCIRefAssign() + and returned via the 'target' parameter. + + Similarly, if the collection element was of type string (OCIString*), + OCICollGetElem() returns pointer to string handle + (i.e. OCIString**). If a new string is assigned, via + OCIStringAssign() or OCIStringAssignText() the type of the target + must be 'OCIString **'. + + If the collection element is of type Oracle number, OCICollGetElem() + returns OCINumber*. The prototype of OCINumberAssign() is shown below: + + sword OCINumberAssign(OCIError *err, const OCINumber *from, + OCINumber *to); + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------- OCICollGetElemArray -----------------------------*/ + +sword OCICollGetElemArray( OCIEnv *env, OCIError *err, const OCIColl *coll, + sb4 index, boolean *exists, void **elem, + void **elemind, uword *nelems); +/* + NAME: OCICollGetElemArray - OCIColl GET pointers to elements from given index + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - pointers to the elements in this collection is returned + index (IN) - starting index of the element + exists (OUT) - set to FALSE if element at the specified index does + not exist else TRUE + elem (OUT) - address of the desired elements is returned + elemind (OUT) [optional] - address of the null indicators information + is returned; if (elemind == NULL) then the null indicator + information will NOT be returned + nelems(IN/OUT) - Upper bound of elem and/or elemind array + DESCRIPTION: + Get the address of the elements from the given position. Optionally + this function also returns the address of the element's null indicator + information. + + The following table describes for each collection element type + what the corresponding element pointer type is. The element pointer + is returned via the 'elem' parameter of OCICollGetElem(). + + Element Type *elem is set to + ----------------------- --------------- + Oracle Number (OCINumber) OCINumber* + Date (OCIDate) OCIDate* + Variable-length string (OCIString*) OCIString** + Variable-length raw (OCIRaw*) OCIRaw** + object reference (OCIRef*) OCIRef** + lob locator (OCILobLocator*) OCILobLocator** + object type (e.g. person) person* + + The element pointer returned by OCICollGetElem() is in a form + such that it can not only be used to access the + element data but also is in a form that can be used as the target + (i.e left-hand-side) of an assignment statement. + + For example, assume the user is iterating over the elements of + a collection whose element type is object reference (OCIRef*). A call + to OCICollGetElem() returns pointer to a reference handle + (i.e. OCIRef**). After getting, the pointer to the collection + element, the user may wish to modify it by assigning a new reference. + This can be accomplished via the ref assignment function shown below: + + sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source, + OCIRef **target ); + + Note that the 'target' parameter of OCIRefAssign() is of type + 'OCIRef**'. Hence OCICollGetElem() returns 'OCIRef**'. + If '*target == NULL' a new ref will be allocated by OCIRefAssign() + and returned via the 'target' parameter. + + Similarly, if the collection element was of type string (OCIString*), + OCICollGetElem() returns pointer to string handle + (i.e. OCIString**). If a new string is assigned, via + OCIStringAssign() or OCIStringAssignText() the type of the target + must be 'OCIString **'. + + If the collection element is of type Oracle number, OCICollGetElem() + returns OCINumber*. The prototype of OCINumberAssign() is shown below: + + sword OCINumberAssign(OCIError *err, const OCINumber *from, + OCINumber *to); + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*----------------------- OCICollAssignElem ---------------------------------*/ + +sword OCICollAssignElem( OCIEnv *env, OCIError *err, sb4 index, + const void *elem, + const void *elemind, OCIColl *coll ); +/* + NAME: OCICollAssignElem - OCIColl ASsign Element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - index of the element whose is assigned to + elem (IN) - element which is assigned from (source element) + elemind (IN) [optional] - pointer to the element's null indicator + information; if (elemind == NULL) then the null indicator + information of the assigned element will be set to non-null. + coll (IN/OUT) - collection to be updated + DESCRIPTION: + Assign the given element value 'elem' to the element at coll[index]. + If the collection is of type nested table, the element at the given + index may not exist (i.e. may have been deleted). In this case, the + given element is inserted at index 'index'. + Otherwise, the element at index 'index' is updated with the value + of 'elem'. + + Note that the given element is deep-copied and + 'elem' is strictly an input parameter. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + given index is out of bounds of the given collection + */ + +/*--------------------------- OCICollAssign ---------------------------------*/ + +sword OCICollAssign( OCIEnv *env, OCIError *err, const OCIColl *rhs, + OCIColl *lhs ); +/* + NAME: OCICollAssign - OCIColl ASsiGn collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - collection to be assigned from + lhs (OUT) - collection to be assigned to + DESCRIPTION: + Assign 'rhs' to 'lhs'. The 'lhs' collection may be decreased or + increased depending upon the size of 'rhs'. If the 'lhs' contains + any elements then the elements will be deleted prior to the + assignment. This function performs a deep-copy. The memory for the + elements comes from the object cache. + + An error is returned if the element types of the lhs and rhs + collections do not match. Also, an error is returned if the + upper-bound of the lhs collection is less than the current number of + elements in the rhs collection. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + type mis-match of lhs and rhs collections + upper-bound of lhs collection is less than the current number of + elements in the rhs collection + */ + +/*--------------------------- OCICollAppend ---------------------------------*/ + +sword OCICollAppend( OCIEnv *env, OCIError *err, const void *elem, + const void *elemind, OCIColl *coll ); +/* + NAME: OCICollAppend - OCIColl APPend collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the element which is appended to the end + of the given collection + elemind (IN) [optional] - pointer to the element's null indicator + information; if (elemind == NULL) then the null indicator + information of the appended element will be set to non-null. + coll (IN/OUT) - updated collection + DESCRIPTION: + Append the given element to the end of the given collection. + Appending an element is equivalent to: + - increasing the size of the collection by 1 element + - updating (deep-copying) the last element's data with the given + element's data + + Note that the pointer to the given element 'elem' will not be saved + by this function. So 'elem' is strictly an input parameter. + An error is returned if the current size of the collection + is equal to the max size (upper-bound) of the collection prior to + appending the element. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + current size of collection == max size of the collection + */ + +/*----------------------------- OCICollTrim ---------------------------------*/ + +sword OCICollTrim( OCIEnv *env, OCIError *err, sb4 trim_num, + OCIColl *coll ); +/* + NAME: OCICollTrim - OCIColl Trim elements from the end of the collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + trim_num (IN) - number of elements to trim + coll (IN/OUT) - 'trim_num' of elements are removed (freed) from the + end of the collection + DESCRIPTION: + Trim the collection by the given number of elements. The elements are + removed from the end of the collection. + + An error is returned if the 'trim_num' is greater than the current + size of the collection. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + 'trim_num' is greater than the current size of the collection. + */ + +/*--------------------------- OCICollIsLocator ------------------------------*/ + +sword OCICollIsLocator(OCIEnv *env, OCIError *err, const OCIColl *coll, + boolean *result ); +/* +Name: OCICollIsLocator - OCIColl indicates whether a collection is locator + based or not. +Parameters: + env(IN) - pointer to OCI environment handle + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection item. + result (OUT) - TRUE if the collection item is a locator, FALSE + otherwise +Description: + Returns TRUE in the result OUT parameter if the collection item is a + locator, otherwise returns FALSE. +Returns: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. +*/ + +/*---------------------------- OCIIterCreate --------------------------------*/ + +sword OCIIterCreate( OCIEnv *env, OCIError *err, const OCIColl *coll, + OCIIter **itr ); +/* + NAME: OCIIterCreate - OCIColl Create an ITerator to scan the collection + elements + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection which will be scanned; the different + collection types are varray and nested table + itr (OUT) - address to the allocated collection iterator is + returned by this function + DESCRIPTION: + Create an iterator to scan the elements of the collection. The + iterator is created in the object cache. The iterator is initialized + to point to the beginning of the collection. + + If the next function (OCIIterNext) is called immediately + after creating the iterator then the first element of the collection + is returned. + If the previous function (OCIIterPrev) is called immediately after + creating the iterator then "at beginning of collection" error is + returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + */ + +/*----------------------------- OCIIterDelete ------------------------------*/ + +sword OCIIterDelete( OCIEnv *env, OCIError *err, OCIIter **itr ); +/* + NAME: OCIIterDelete - OCIColl Delete ITerator + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN/OUT) - the allocated collection iterator is destroyed and + the 'itr' is set to NULL prior to returning + DESCRIPTION: + Delete the iterator which was previously created by a call to + OCIIterCreate. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + to be discovered + */ + +/*----------------------------- OCIIterInit ---------------------------------*/ + +sword OCIIterInit( OCIEnv *env, OCIError *err, const OCIColl *coll, + OCIIter *itr ); +/* + NAME: OCIIterInit - OCIColl Initialize ITerator to scan the given + collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection which will be scanned; the different + collection types are varray and nested table + itr (IN/OUT) - pointer to an allocated collection iterator + DESCRIPTION: + Initializes the given iterator to point to the beginning of the + given collection. This function can be used to: + + a. reset an iterator to point back to the beginning of the collection + b. reuse an allocated iterator to scan a different collection + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------ OCIIterGetCurrent --------------------------------*/ + +sword OCIIterGetCurrent( OCIEnv *env, OCIError *err, const OCIIter *itr, + void **elem, void **elemind ); +/* + NAME: OCIIterGetCurrent - OCIColl Iterator based, get CURrent collection + element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN) - iterator which points to the current element + elem (OUT) - address of the element pointed by the iterator is returned + elemind (OUT) [optional] - address of the element's null indicator + information is returned; if (elemind == NULL) then the null + indicator information will NOT be returned + DESCRIPTION: + Returns pointer to the current element and its corresponding null + information. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------------ OCIIterNext --------------------------------*/ + +sword OCIIterNext( OCIEnv *env, OCIError *err, OCIIter *itr, + void **elem, void **elemind, boolean *eoc ); +/* + NAME: OCIIterNext - OCIColl Iterator based, get NeXT collection element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN/OUT) - iterator is updated to point to the next element + elem (OUT) - after updating the iterator to point to the next element, + address of the element is returned + elemind (OUT) [optional] - address of the element's null indicator + information is returned; if (elemind == NULL) then the null + indicator information will NOT be returned + eoc (OUT) - TRUE if iterator is at End Of Collection (i.e. next + element does not exist) else FALSE + DESCRIPTION: + Returns pointer to the next element and its corresponding null + information. The iterator is updated to point to the next element. + + If the iterator is pointing to the last element of the collection + prior to executing this function, then calling this function will + set eoc flag to TRUE. The iterator will be left unchanged in this + situation. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------------ OCIIterPrev --------------------------------*/ + +sword OCIIterPrev( OCIEnv *env, OCIError *err, OCIIter *itr, + void **elem, void **elemind, boolean *boc ); +/* + NAME: OCIIterPrev - OCIColl Iterator based, get PReVious collection element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN/OUT) - iterator is updated to point to the previous + element + elem (OUT) - after updating the iterator to point to the previous + element, address of the element is returned + elemind (OUT) [optional] - address of the element's null indicator + information is returned; if (elemind == NULL) then the null + indicator information will NOT be returned + boc (OUT) - TRUE if iterator is at Beginning Of Collection (i.e. + previous element does not exist) else FALSE. + DESCRIPTION: + Returns pointer to the previous element and its corresponding null + information. The iterator is updated to point to the previous element. + + If the iterator is pointing to the first element of the collection + prior to executing this function, then calling this function will + set 'boc' to TRUE. The iterator will be left unchanged in this + situation. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*****************************************************************************/ +/* FUNCTIONS WHICH OPERATE ONLY ON NESTED TABLE OCITable*() */ +/*****************************************************************************/ + +/*---------------------------- OCITableSize ---------------------------------*/ + +sword OCITableSize( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 *size); +/* + NAME: OCITableSize - OCITable return current SIZe of the given + nested table (not including deleted elements) + PARAMETERS: + env(IN) - pointer to OCI environment handle + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - nested table whose number of elements is returned + size (OUT) - current number of elements in the nested table. The count + does not include deleted elements. + DESCRIPTION: + Returns the count of elements in the given nested table. + + The count returned by OCITableSize() will be decremented upon + deleting elements from the nested table. So, this count DOES NOT + includes any "holes" created by deleting elements. + For example: + + OCITableSize(...); + // assume 'size' returned is equal to 5 + OCITableDelete(...); // delete one element + OCITableSize(...); + // 'size' returned will be equal to 4 + + To get the count plus the count of deleted elements use + OCICollSize(). Continuing the above example, + + OCICollSize(...) + // 'size' returned will still be equal to 5 + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + error during loading of nested table into object cache + any of the input parameters is null + */ + +/*---------------------- OCITableExists ---------------------------------*/ + +sword OCITableExists( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 index, boolean *exists ); +/* + NAME: OCITableExists - OCITable test whether element at the given index + EXIsts + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - table in which the given index is checked + index (IN) - index of the element which is checked for existence + exists (OUT) - set to TRUE if element at given 'index' exists + else set to FALSE + DESCRIPTION: + Test whether an element exists at the given 'index'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*--------------------------- OCITableDelete -------------------------------*/ + +sword OCITableDelete( OCIEnv *env, OCIError *err, sb4 index, + OCITable *tbl ); +/* + NAME: OCITableDelete - OCITable DELete element at the specified index + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - index of the element which must be deleted + tbl (IN) - table whose element is deleted + DESCRIPTION: + Delete the element at the given 'index'. Note that the position + ordinals of the remaining elements of the table is not changed by the + delete operation. So delete creates "holes" in the table. + + An error is returned if the element at the specified 'index' has + been previously deleted. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + given index is not valid + */ + +/*--------------------------- OCITableFirst ---------------------------------*/ + +sword OCITableFirst( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 *index ); +/* + NAME: OCITableFirst - OCITable return FirST index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - table which is scanned + index (OUT) - first index of the element which exists in the given + table is returned + DESCRIPTION: + Return the first index of the element which exists in the given + table. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + table is empty + */ + +/*---------------------------- OCITableLast ---------------------------------*/ + +sword OCITableLast( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 *index ); +/* + NAME: OCITableFirst - OCITable return LaST index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - table which is scanned + index (OUT) - last index of the element which exists in the given + table is returned + DESCRIPTION: + Return the last index of the element which exists in the given + table. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + table is empty + */ + +/*---------------------------- OCITableNext ---------------------------------*/ + +sword OCITableNext( OCIEnv *env, OCIError *err, sb4 index, + const OCITable *tbl, sb4 *next_index, + boolean *exists ); +/* + NAME: OCITableNext - OCITable return NeXT available index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - starting at 'index' the index of the next element + which exists is returned + tbl (IN) - table which is scanned + next_index (OUT) - index of the next element which exists + is returned + exists (OUT) - FALSE if no next index available else TRUE + DESCRIPTION: + Return the smallest position j, greater than 'index', such that + exists(j) is TRUE. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + no next index available + */ + +/*---------------------------- OCITablePrev ---------------------------------*/ + +sword OCITablePrev( OCIEnv *env, OCIError *err, sb4 index, + const OCITable *tbl, sb4 *prev_index, + boolean *exists ); +/* + NAME: OCITablePrev - OCITable return PReVious available index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - starting at 'index' the index of the previous element + which exists is returned + tbl (IN) - table which is scanned + prev_index (OUT) - index of the previous element which exists + is returned + exists (OUT) - FALSE if no next index available else TRUE + DESCRIPTION: + Return the largest position j, less than 'index', such that + exists(j) is TRUE. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + no previous index available + */ + +/*------------------------ OCINumberToLnx -----------------------------------*/ +/* void OCINumberToLnx(/o_ OCINumber *num _o/); */ + +#define OCINumberToLnx(num) ((lnxnum_t *)num) + +/* + NAME: OCINumberToLnx + PARAMETERS: + num (IN) - OCINumber to convert ; + DESCRIPTION: + Converts OCINumber to its internal lnx format + This is not to be used in Public interfaces , but + has been provided due to special requirements from + SQLPLUS development group as they require to call + Core funtions directly . +*/ + +/* OCI representation of XMLType */ +typedef struct OCIXMLType OCIXMLType; + +/* OCI representation of OCIDomDocument */ +typedef struct OCIDOMDocument OCIDOMDocument; + +/* OCI representation for the Binary XML repository context */ +typedef struct OCIBinXmlReposCtx OCIBinXmlReposCtx; + +#endif /* ORL_ORACLE */ diff --git a/OCI/include/oro.h b/OCI/include/oro.h new file mode 100644 index 0000000..e825a5c --- /dev/null +++ b/OCI/include/oro.h @@ -0,0 +1,883 @@ +/* Copyright (c) 1994, 2003, Oracle Corporation. All rights reserved. */ + +/* + NAME + OCI - Oracle Object Interface for External/Internal/Kernel Clients + + DESCRIPTION + This header file contains Oracle object interface definitions which + can be included by external user applications, tools, as well as + the kernel. It defines types and constants that are common to all + object interface which is being defined in several other header files + (e.g., ori.h, ort.h, and orl.h). + + RELATED DOCUMENTS + TBD + + INSPECTION STATUS [[ deletable if no inspection ]] + Inspection date: [[ date of the last logging meeting ]] + Inspection status: [[ exited, not exited, or N/A if exit is not a goal ]] + Estimated increasing cost defects per page: + Rule sets: [[ rule sets inspected against or planned to be + inspected against ]] + + ACCEPTANCE REVIEW STATUS [[ deletable if no approval review ]] + Review date: [[ date of the meeting where issues were logged and the + approval status was decided ]] + Review status: [[ current status: accepted, conditionally accepted, + major revision required, rejected ]] + Reviewers: [[ names of the members on the review team ]] + + PUBLIC FUNCTIONS + + EXAMPLES + Examples are given in the description of each function or macro where + relevant. + + MODIFIED + mnanal 06/09/03 - backout of fix 2836388 + mnanal 05/14/03 - bug-2836388 + srseshad 11/27/02 - Change OCI_TYPECODE_BFLOAT/BDOUBLE codes + rxgovind 10/09/02 - add OCI_TYPECODE_UROWID + mxyang 09/17/02 - grabtrans 'mmorsi_obj_float' + srseshad 09/11/02 - + srseshad 09/01/02 - + aahluwal 06/03/02 - bug 2360115 + celsbern 10/19/01 - merge LOG to MAIN + rxgovind 10/16/01 - update typecodes + rxgovind 09/19/01 - add typecodes + rkasamse 08/15/01 - add OCI_DURATION_USER_CALLBACK + jchai 09/24/01 - add type code for PLS_INTEGER + porangas 08/22/01 - Fix bug#1776434 + schatter 04/09/01 - merge 1456235: define OCI_DURATION_INVALID + rdani 10/12/00 - 1449943 NOCOPY and PIPELINE + ciyer 05/26/00 - short names for abstract, overriding + rkasamse 05/25/00 - OCCI enhancements + smuralid 05/11/00 - OCITypeMethodFlags - add NOT INSTANTIABLE, OVERRIDING + rxgovind 05/09/00 - add OCI_TYPECODE_NONE + tnbui 07/28/99 - Remove OCI_TYPECODE_TIMESTAMP_ITZ + tnbui 07/21/99 - TS LOCAL TZ + thoang 06/21/99 - Add OCI_TYPECODE_TIMESTAMP_ITZ + thoang 03/04/99 - Add datetime datatypes + rkasamse 10/20/98 - add OCI_ATTR_CACHE_ARRAYFLUSH + rkasamse 10/29/98 - add OCI_DURATION_CALLOUT + rkasamse 04/28/98 - OCI_OBJECT_DETECTCHANGE -> OCI_ATTR_OBJECT_DETECTCHAN + rkasamse 04/28/98 - OCI_OBJECT_NEWNOTNULL -> OCI_ATTR_OBJECT_NEWNOTNULL + rkasamse 04/23/98 - add OCI_OBJECT_DETECTCHANGE + rkasamse 04/03/98 - add OCI_OBJECT_NEWNOTNULL + pmitra 04/01/98 - OCI_LOCK_X_NOWAIT added + rxgovind 02/18/98 - add OCI_TYPECODE_OPAQUE + rkasamse 02/13/98 - Add OCI_DURATION_PROCESS + cxcheng 07/28/97 - fix compile with SLSHORTNAME + skrishna 07/14/97 - add OCIObjectGetProperty + cxcheng 04/30/97 - make OCITypeParamMode values consistent with PL/SQL + skrishna 04/28/97 - undocument OCIObjectProperty & OCIObjectEvent + cxcheng 03/29/97 - remove all remaining short names + sthakur 03/20/97 - add casts to constants + cxcheng 02/21/97 - temporarily put SLSHORTNAME for PL/SQL + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + lchidamb 01/20/97 - update OCIRef comments + sgollapu 11/19/96 - Add OCI type codes for BOOL,REC,and TAB + cxcheng 11/19/96 - more typecode changes + cxcheng 11/13/96 - add #include for ocidfn.h + cxcheng 11/13/96 - add OCI_TYPECODE_ADT for compatibility + cxcheng 11/12/96 - add SQLT_NCO for named collection + cxcheng 11/11/96 - more changes to typecodes + cxcheng 11/07/96 - #define OCI_TYPECODE_MLSLABEL to SQLT_LAB + cxcheng 11/06/96 - fix #define omission for OROTCNAT + cxcheng 10/30/96 - move OCI_TYPECODE_* to ocidfn.h as SQLT_* + cxcheng 10/28/96 - more beautification changes + jboonleu 10/29/96 - add flags for freeing object + dchatter 10/26/96 - delete redef of OCISvcCtx, OCIError, OCIEnv + cxcheng 10/15/96 - more changes + cxcheng 10/14/96 - more final fixes to constants + mluong 10/11/96 - + mluong 10/11/96 - KOCON and KONSP are in lowercase + mluong 10/11/96 - add some define per Calvin + cxcheng 10/09/96 - add #define for OROOCOSFN to OCI_COPY_NOREF + jboonleu 10/08/96 - change OROOCOSFN to OCICopyFlag + jboonleu 10/07/96 - use new OCI names for cache options + cxcheng 10/07/96 - add OROTCS02 for KOTTCBRI and OROTCS03 as spare + cxcheng 10/07/96 - more lint fixes + cxcheng 10/02/96 - move oronsp to ko.h as konsp + cxcheng 10/01/96 - add long names for readability + cxcheng 10/01/96 - remove orotty and orotal + rjenkins 09/28/96 - 2k char 4k varchar2 + jboonleu 09/27/96 - add macro used only in beta2 + cxcheng 09/27/96 - move oroenv to oroenv.h + cxcheng 09/24/96 - remove unnecessary orotyp + cxcheng 09/25/96 - add typecode OROTCS01 as placeholder for lob pointer + cxcheng 09/20/96 - add TDO load option orotgo + jboonleu 09/18/96 - add OROOPOREC + jboonleu 09/10/96 - add OROOPODFL + jweisz 08/27/96 - add SQL internal typecode OROTCS00 + cxcheng 08/02/96 - add PLSQL internal typecodes OROTCP.. + cxcheng 08/01/96 - add OROTCFAR to fill up space left by OROTCCAR + jboonleu 07/16/96 - new pin option + cxcheng 06/18/96 - add casts to OROTNOPRE and OROTNOSCL + cxcheng 05/29/96 - change OROTCNPT back to OROTCDOM + vkrishna 05/27/96 - add OROTCCAR + cxcheng 05/17/96 - replace OROTCFAR with OROTCCAR + cxcheng 05/08/96 - change orotmf from ub1 to ub2 + cxcheng 05/07/96 - fix public defines for method types + cxcheng 04/30/96 - change OROTCDOM to OROTCNPT + cxcheng 04/15/96 - remove obsolete OROTTYICT + jboonleu 04/12/96 - add new pin option + sthakur 04/12/96 - add indicator type and indicator status + cxcheng 04/10/96 - add function parameter codes for ORT/KOT + cxcheng 04/03/96 - replace OROTCFAR as OROTCCAR + jwijaya 03/29/96 - add OROTTCCAR + jwijaya 03/27/96 - better comments for orotc + cxcheng 02/23/96 - add typecodes for SMALLINT and VARCHAR2 + skrishna 02/22/96 - add oroind - null indicator type + cxcheng 02/21/96 - change lob character codes to OROTCCLB, OROTCBLB... + jboonleu 02/06/96 - new value for predefined duration + cxcheng 01/12/96 - add OROTCCLO, OROTCBLO, OROTCFIL to orotc + cxcheng 12/05/95 - add OROTCDOM and OROTCAAT to orotc + skotsovo 10/30/95 - reserve space for internal 'oid' type + jwijaya 10/20/95 - support variable-length ref + cxcheng 10/03/95 - add OROTMFOR for ordering function to orotmf + cxcheng 10/03/95 - Adding the ordering function type to orotmf + jboonleu 09/28/95 - set OROODTPRE + jboonleu 09/25/95 - add oroodt + skotsovo 03/10/95 - update to only include release 1 + jboonleu 02/15/95 - add OROOPOREC, remove orocro, oroolo + skotsovo 01/30/95 - add default max lengths for varrays and vstrings + skotsovo 01/24/95 - categorize sint32, double, and real as number types + (with precision and scale) instead of scalar types. + skotsovo 12/20/94 - add release 1 types + skotsovo 12/12/94 - update according to new ots doc + skotsovo 12/01/94 - add default precision and scale + jwijaya 11/15/94 - rename ORONSPTAB to ORONSPEXT + jwijaya 10/25/94 - tint + jwijaya 10/06/94 - add namespace + jwijaya 10/02/94 - connection handle -> connection number + skotsovo 09/12/94 - keep 0 as uninitialized value for ORT consts + skotsovo 08/24/94 - fix orotec + skotsovo 08/17/94 - modify type code names + skotsovo 08/12/94 - fix 141 lint errors + skotsovo 07/25/94 - modify categorization of complex types (orotc) + skotsovo 07/07/94 - change typecode enum values & add decimal type + skotsovo 07/01/94 - change order of typecodes + jwijaya 06/15/94 - review + jboonleu 06/13/94 - add comments for the object cache options + jwijaya 06/13/94 - adhere to the header file template + skotsovo 06/09/94 - make ots scalar type names consistent with the ots + document + jwijaya 06/07/94 - include oratypes.h instead of s.h + skotsovo 05/24/94 - change typecodes + jwijaya 05/23/94 - fix comments of ororef + skotsovo 05/19/94 - remove type composition + skotsovo 05/09/94 - modified orotc according to new OTS document + jwijaya 05/03/94 - oroid and ororef + jwijaya 01/26/94 - Creation +*/ + + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN_ORACLE +#include +#endif + +#ifndef ORO_ORACLE +#define ORO_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCIDuration oroodt +#define OCIInd oroind +#define OCILockOpt oroolm +#define OCIMarkOpt oroomo +#define OCIObjectEvent orocev +#define OCIObjectProperty oroopr +#define OCIPinOpt oroopo +#define OCIRef ororef +#define OCIRefreshOpt orooro +#define OCITypeCode orotc +#define OCITypeEncap orotec +#define OCITypeGetOpt orotgo +#define OCITypeMethodFlag orotmf +#define OCITypeParamMode orotpm +#define OCIObjectPropId oroopi +#define OCIObjectLifetime oroolft +#define OCIObjectMarkstatus oroomst +#define OCI_LOCK_NONE OROOLMNUL +#define OCI_LOCK_X OROOLMX +#define OCI_LOCK_X_NOWAIT OROOLMXNW +#define OCI_MARK_DEFAULT OROOMODFL +#define OCI_MARK_NONE OROOMONON +#define OCI_MARK_UPDATE OROOMOUPD +#define OCI_OBJECTEVENT_AFTER_FLUSH OROCEVAFL +#define OCI_OBJECTEVENT_AFTER_REFRESH OROCEVARF +#define OCI_OBJECTEVENT_BEFORE_FLUSH OROCEVBFL +#define OCI_OBJECTEVENT_BEFORE_REFRESH OROCEVBRF +#define OCI_OBJECTEVENT_WHEN_LOCK OROCEVWLK +#define OCI_OBJECTEVENT_WHEN_MARK_DELETED OROCEVWDL +#define OCI_OBJECTEVENT_WHEN_MARK_UPDATED OROCEVWUP +#define OCI_OBJECTEVENT_WHEN_UNMARK OROCEVWUM +#define OCI_OBJECTPROP_DIRTIED OROOPRDRT +#define OCI_OBJECTPROP_LOADED OROOPRLOD +#define OCI_OBJECTPROP_LOCKED OROOPRLCK +#define OCI_PIN_ANY OROOPOANY +#define OCI_PIN_DEFAULT OROOPODFL +#define OCI_PIN_LATEST OROOPOLST +#define OCI_PIN_RECENT OROOPOREC +#define OCI_REFRESH_LOADED OROOROLOD +#define OCI_TYPEENCAP_PRIVATE OROTECPVT +#define OCI_TYPEENCAP_PUBLIC OROTECPUB +#define OCI_TYPEGET_ALL OROTGOALL +#define OCI_TYPEGET_HEADER OROTGOHDR +#define OCI_TYPEMETHOD_CONSTANT OROTMCON +#define OCI_TYPEMETHOD_CONSTRUCTOR OROTMCSTR +#define OCI_TYPEMETHOD_DESTRUCTOR OROTMDSTR +#define OCI_TYPEMETHOD_INLINE OROTMINL +#define OCI_TYPEMETHOD_MAP OROTMMAP +#define OCI_TYPEMETHOD_OPERATOR OROTMOP +#define OCI_TYPEMETHOD_ORDER OROTMOR +#define OCI_TYPEMETHOD_RNDS OROTMRDS +#define OCI_TYPEMETHOD_RNPS OROTMRPS +#define OCI_TYPEMETHOD_SELFISH OROTMSLF +#define OCI_TYPEMETHOD_VIRTUAL OROTMVRT +#define OCI_TYPEMETHOD_WNDS OROTMWDS +#define OCI_TYPEMETHOD_WNPS OROTMWPS +#define OCI_TYPEMETHOD_ABSTRACT OROTMABSTRACT +#define OCI_TYPEMETHOD_OVERRIDING OROTMOVERRIDING +#define OCI_TYPEMETHOD_PIPELINED OROTMPIPELINED +#define OCI_TYPEPARAM_BYREF OROTPMREF +#define OCI_TYPEPARAM_IN OROTPMIN +#define OCI_TYPEPARAM_INOUT OROTPMIO +#define OCI_TYPEPARAM_OUT OROTPMOUT +#define OCI_TYPEPARAM_OUTNCPY OROTPMOUTNCPY +#define OCI_TYPEPARAM_INOUTNCPY OROTPMIONCPY + +#endif /* SLSHORTNAME */ + + +/*---------------------------------------------------------------------------*/ +/* PUBLIC TYPES, CONSTANTS AND MACROS */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* GENERAL OBJECT TYPES, CONSTANTS, MACROS */ +/*---------------------------------------------------------------------------*/ + +/*------------------------- OBJECT REFERENCE (REF) --------------------------*/ + +typedef struct OCIRef OCIRef; +/* + * OCIRef - OCI object REFerence + * + * In the Oracle object runtime environment, an object is identified by an + * object reference (ref) which contains the object identifier plus other + * runtime information. The contents of a ref is opaque to clients. Use + * OCIObjectNew() to construct a ref. + */ + + +/*--------------------------- OBJECT INDICATOR ------------------------------*/ + +typedef sb2 OCIInd; +/* + * OCIInd -- a variable of this type contains (null) indicator information + */ + +#define OCI_IND_NOTNULL (OCIInd)0 /* not NULL */ +#define OCI_IND_NULL (OCIInd)(-1) /* NULL */ +#define OCI_IND_BADNULL (OCIInd)(-2) /* BAD NULL */ +#define OCI_IND_NOTNULLABLE (OCIInd)(-3) /* not NULLable */ + +/*---------------------------------------------------------------------------*/ +/* OBJECT CACHE */ +/*---------------------------------------------------------------------------*/ + +/* To enable object change detection mode, set this to TRUE */ +#define OCI_ATTR_OBJECT_DETECTCHANGE 0x00000020 + +/* To enable object creation with non-NULL attributes by default, set the + following to TRUE. + By default, object is created with NULL attributes +*/ +#define OCI_ATTR_OBJECT_NEWNOTNULL 0x00000010 + +/* To enable sorting of the objects that belong to the same table + before being flushed through OCICacheFlush. + Please note that by enabling this object cache will not be flushing + the objects in the same order they were dirtied */ +#define OCI_ATTR_CACHE_ARRAYFLUSH 0x00000040 + +/*--------------------------- OBJECT PIN OPTION -----------------------------*/ + +enum OCIPinOpt +{ + /* 0 = uninitialized */ + OCI_PIN_DEFAULT = 1, /* default pin option */ + OCI_PIN_ANY = 3, /* pin any copy of the object */ + OCI_PIN_RECENT = 4, /* pin recent copy of the object */ + OCI_PIN_LATEST = 5 /* pin latest copy of the object */ +}; +typedef enum OCIPinOpt OCIPinOpt; + +/* + * OCIPinOpt - OCI object Pin Option + * + * In the Oracle object runtime environment, the program has the option to + * specify which copy of the object to pin. + * + * OCI_PINOPT_DEFAULT pins an object using the default pin option. The default + * pin option can be set as an attribute of the OCI environment handle + * (OCI_ATTR_PINTOPTION). The value of the default pin option can be + * OCI_PINOPT_ANY, OCI_PINOPT_RECENT, or OCI_PIN_LATEST. The default option + * is initialized to OCI_PINOPT_ANY. + * + * OCI_PIN_ANY pins any copy of the object. The object is pinned + * using the following criteria: + * If the object copy is not loaded, load it from the persistent store. + * Otherwise, the loaded object copy is returned to the program. + * + * OCI_PIN_RECENT pins the latest copy of an object. The object is + * pinned using the following criteria: + * If the object is not loaded, load the object from the persistent store + * from the latest version. + * If the object is not loaded in the current transaction and it is not + * dirtied, the object is refreshed from the latest version. + * Otherwise, the loaded object copy is returned to the program. + * + * OCI_PINOPT_LATEST pins the latest copy of an object. The object copy is + * pinned using the following criteria: + * If the object copy is not loaded, load it from the persistent store. + * If the object copy is loaded and dirtied, it is returned to the program. + * Otherwise, the loaded object copy is refreshed from the persistent store. + */ + + + +/*--------------------------- OBJECT LOCK OPTION ----------------------------*/ + +enum OCILockOpt +{ + /* 0 = uninitialized */ + OCI_LOCK_NONE = 1, /* null (same as no lock) */ + OCI_LOCK_X = 2, /* exclusive lock */ + OCI_LOCK_X_NOWAIT = 3 /* exclusive lock, do not wait */ +}; +typedef enum OCILockOpt OCILockOpt; +/* + * OCILockOpt - OCI object LOCK Option + * + * This option is used to specify the locking preferences when an object is + * loaded from the server. + */ + + +/*------------------------- OBJECT MODIFYING OPTION -------------------------*/ + +enum OCIMarkOpt +{ + /* 0 = uninitialized */ + OCI_MARK_DEFAULT = 1, /* default (the same as OCI_MARK_NONE) */ + OCI_MARK_NONE = OCI_MARK_DEFAULT, /* object has not been modified */ + OCI_MARK_UPDATE /* object is to be updated */ +}; +typedef enum OCIMarkOpt OCIMarkOpt; +/* + * OCIMarkOpt - OCI object Mark option + * + * When the object is marked updated, the client has to specify how the + * object is intended to be changed. + */ + +/*-------------------------- OBJECT Duration --------------------------------*/ + +typedef ub2 OCIDuration; + +#define OCI_DURATION_INVALID 0xFFFF /* Invalid duration */ +#define OCI_DURATION_BEGIN (OCIDuration)10 + /* beginning sequence of duration */ +#define OCI_DURATION_NULL (OCIDuration)(OCI_DURATION_BEGIN-1) + /* null duration */ +#define OCI_DURATION_DEFAULT (OCIDuration)(OCI_DURATION_BEGIN-2) /* default */ +#define OCI_DURATION_USER_CALLBACK (OCIDuration)(OCI_DURATION_BEGIN-3) +#define OCI_DURATION_NEXT (OCIDuration)(OCI_DURATION_BEGIN-4) + /* next special duration */ +#define OCI_DURATION_SESSION (OCIDuration)(OCI_DURATION_BEGIN) + /* the end of user session */ +#define OCI_DURATION_TRANS (OCIDuration)(OCI_DURATION_BEGIN+1) + /* the end of user transaction */ +/****************************************************************************** +** DO NOT USE OCI_DURATION_CALL. IT IS UNSUPPORTED ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ +#define OCI_DURATION_CALL (OCIDuration)(OCI_DURATION_BEGIN+2) + /* the end of user client/server call */ +#define OCI_DURATION_STATEMENT (OCIDuration)(OCI_DURATION_BEGIN+3) + +/* This is to be used only during callouts. It is similar to that +of OCI_DURATION_CALL, but lasts only for the duration of a callout. +Its heap is from PGA */ +#define OCI_DURATION_CALLOUT (OCIDuration)(OCI_DURATION_BEGIN+4) + +#define OCI_DURATION_LAST OCI_DURATION_CALLOUT + /* last of predefined durations */ + +/* This is not being treated as other predefined durations such as + SESSION, CALL etc, because this would not have an entry in the duration + table and its functionality is primitive such that only allocate, free, + resize memory are allowed, but one cannot create subduration out of this +*/ +#define OCI_DURATION_PROCESS (OCIDuration)(OCI_DURATION_BEGIN-5) + +/* + * OCIDuration - OCI object duration + * + * A client can specify the duration of which an object is pinned (pin + * duration) and the duration of which the object is in memory (allocation + * duration). If the objects are still pinned at the end of the pin duration, + * the object cache manager will automatically unpin the objects for the + * client. If the objects still exist at the end of the allocation duration, + * the object cache manager will automatically free the objects for the client. + * + * Objects that are pinned with the option OCI_DURATION_TRANS will get unpinned + * automatically at the end of the current transaction. + * + * Objects that are pinned with the option OCI_DURATION_SESSION will get + * unpinned automatically at the end of the current session (connection). + * + * The option OCI_DURATION_NULL is used when the client does not want to set + * the pin duration. If the object is already loaded into the cache, then the + * pin duration will remain the same. If the object is not yet loaded, the + * pin duration of the object will be set to OCI_DURATION_DEFAULT. + */ + +/*----------------------------- OBJECT PROPERTY -----------------------------*/ + +/****************************************************************************** +** DO NOT USE OCIObjectProperty. IT IS UNSUPPORTED ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ +enum OCIObjectProperty +{ + /* 0 = uninitialized */ + OCI_OBJECTPROP_DIRTIED = 1, /* dirty objects */ + OCI_OBJECTPROP_LOADED, /* objects loaded in the transaction */ + OCI_OBJECTPROP_LOCKED /* locked objects */ +}; +typedef enum OCIObjectProperty OCIObjectProperty; +/* + * OCIObjectProperty -- OCI Object Property + * This specifies the properties of objects in the object cache. + */ + +/*------------------------- CACHE REFRESH OPTION ---------------------------*/ + +enum OCIRefreshOpt +{ + /* 0 = uninitialized */ + OCI_REFRESH_LOADED = 1 /* refresh objects loaded in the transaction */ +}; +typedef enum OCIRefreshOpt OCIRefreshOpt; +/* + * OCIRefreshOpt - OCI cache Refresh Option + * This option is used to specify the set of objects to be refreshed. + * + * OCI_REFRESH_LOAD refreshes the objects that are loaded in the current + * transaction. + */ + +/*-------------------------------- OBJECT EVENT -----------------------------*/ + +/****************************************************************************** +** DO NOT USE OCIObjectEvent. IT IS UNSUPPORTED ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ +enum OCIObjectEvent +{ + /* 0 = uninitialized */ + OCI_OBJECTEVENT_BEFORE_FLUSH = 1, /* before flushing the cache */ + OCI_OBJECTEVENT_AFTER_FLUSH, /* after flushing the cache */ + OCI_OBJECTEVENT_BEFORE_REFRESH, /* before refreshing the cache */ + OCI_OBJECTEVENT_AFTER_REFRESH, /* after refreshing the cache */ + OCI_OBJECTEVENT_WHEN_MARK_UPDATED, /* when an object is marked updated */ + OCI_OBJECTEVENT_WHEN_MARK_DELETED, /* when an object is marked deleted */ + OCI_OBJECTEVENT_WHEN_UNMARK, /* when an object is being unmarked */ + OCI_OBJECTEVENT_WHEN_LOCK /* when an object is being locked */ +}; +typedef enum OCIObjectEvent OCIObjectEvent; +/* + * OCIObjectEvent -- OCI Object Event + * This specifies the kind of event that is supported by the object + * cache. The program can register a callback that is invoked when the + * specified event occurs. + */ + +/*----------------------------- OBJECT COPY OPTION --------------------------*/ +#define OCI_OBJECTCOPY_NOREF (ub1)0x01 +/* + * OCIObjectCopyFlag - Object copy flag + * + * If OCI_OBJECTCOPY_NOREF is specified when copying an instance, the + * reference and lob will not be copied to the target instance. + */ + +/*----------------------------- OBJECT FREE OPTION --------------------------*/ +#define OCI_OBJECTFREE_FORCE (ub2)0x0001 +#define OCI_OBJECTFREE_NONULL (ub2)0x0002 +#define OCI_OBJECTFREE_HEADER (ub2)0x0004 +/* + * OCIObjectFreeFlag - Object free flag + * + * If OCI_OBJECTCOPY_FORCE is specified when freeing an instance, the instance + * is freed regardless it is pinned or diritied. + * If OCI_OBJECTCOPY_NONULL is specified when freeing an instance, the null + * structure is not freed. + */ + +/*----------------------- OBJECT PROPERTY ID -------------------------------*/ + +typedef ub1 OCIObjectPropId; +#define OCI_OBJECTPROP_LIFETIME 1 /* persistent or transient or value */ +#define OCI_OBJECTPROP_SCHEMA 2 /* schema name of table containing object */ +#define OCI_OBJECTPROP_TABLE 3 /* table name of table containing object */ +#define OCI_OBJECTPROP_PIN_DURATION 4 /* pin duartion of object */ +#define OCI_OBJECTPROP_ALLOC_DURATION 5 /* alloc duartion of object */ +#define OCI_OBJECTPROP_LOCK 6 /* lock status of object */ +#define OCI_OBJECTPROP_MARKSTATUS 7 /* mark status of object */ +#define OCI_OBJECTPROP_VIEW 8 /* is object a view object or not? */ + +/* + * OCIObjectPropId - OCI Object Property Id + * Identifies the different properties of objects. + */ + +/*----------------------- OBJECT LIFETIME ----------------------------------*/ + +enum OCIObjectLifetime +{ + /* 0 = uninitialized */ + OCI_OBJECT_PERSISTENT = 1, /* persistent object */ + OCI_OBJECT_TRANSIENT, /* transient object */ + OCI_OBJECT_VALUE /* value object */ +}; +typedef enum OCIObjectLifetime OCIObjectLifetime; +/* + * OCIObjectLifetime - OCI Object Lifetime + * Classifies objects depending upon the lifetime and referenceability + * of the object. + */ + +/*----------------------- OBJECT MARK STATUS -------------------------------*/ + +typedef uword OCIObjectMarkStatus; +#define OCI_OBJECT_NEW 0x0001 /* new object */ +#define OCI_OBJECT_DELETED 0x0002 /* object marked deleted */ +#define OCI_OBJECT_UPDATED 0x0004 /* object marked updated */ +/* + * OCIObjectMarkStatus - OCI Object Mark Status + * Status of the object - new or updated or deleted + */ + +/* macros to test the object mark status */ +#define OCI_OBJECT_IS_UPDATED(flag) bit((flag), OCI_OBJECT_UPDATED) +#define OCI_OBJECT_IS_DELETED(flag) bit((flag), OCI_OBJECT_DELETED) +#define OCI_OBJECT_IS_NEW(flag) bit((flag), OCI_OBJECT_NEW) +#define OCI_OBJECT_IS_DIRTY(flag) \ + bit((flag), OCI_OBJECT_UPDATED|OCI_OBJECT_NEW|OCI_OBJECT_DELETED) + +/*---------------------------------------------------------------------------*/ +/* TYPE MANAGER */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------ TYPE CODE ----------------------------------*/ + +/* + * Type manager typecodes + * + * These are typecodes designed to be used with the type manager; + * they also include longer, more readable versions of existing SQLT names. + * Those types that are directly related to existing SQLT types are #define'd + * to their SQLT equivalents. + * + * The type manager typecodes are designed to be useable for all OCI calls. + * They are in the range from 192 to 320 for typecodes, so as not to conflict + * with existing OCI SQLT typecodes (see ocidfn.h). + */ + +#define OCI_TYPECODE_REF SQLT_REF /* SQL/OTS OBJECT REFERENCE */ +#define OCI_TYPECODE_DATE SQLT_DAT /* SQL DATE OTS DATE */ +#define OCI_TYPECODE_SIGNED8 27 /* SQL SIGNED INTEGER(8) OTS SINT8 */ +#define OCI_TYPECODE_SIGNED16 28 /* SQL SIGNED INTEGER(16) OTS SINT16 */ +#define OCI_TYPECODE_SIGNED32 29 /* SQL SIGNED INTEGER(32) OTS SINT32 */ +#define OCI_TYPECODE_REAL 21 /* SQL REAL OTS SQL_REAL */ +#define OCI_TYPECODE_DOUBLE 22 /* SQL DOUBLE PRECISION OTS SQL_DOUBLE */ +#define OCI_TYPECODE_BFLOAT SQLT_IBFLOAT /* Binary float */ +#define OCI_TYPECODE_BDOUBLE SQLT_IBDOUBLE /* Binary double */ +#define OCI_TYPECODE_FLOAT SQLT_FLT /* SQL FLOAT(P) OTS FLOAT(P) */ +#define OCI_TYPECODE_NUMBER SQLT_NUM/* SQL NUMBER(P S) OTS NUMBER(P S) */ +#define OCI_TYPECODE_DECIMAL SQLT_PDN + /* SQL DECIMAL(P S) OTS DECIMAL(P S) */ +#define OCI_TYPECODE_UNSIGNED8 SQLT_BIN + /* SQL UNSIGNED INTEGER(8) OTS UINT8 */ +#define OCI_TYPECODE_UNSIGNED16 25 /* SQL UNSIGNED INTEGER(16) OTS UINT16 */ +#define OCI_TYPECODE_UNSIGNED32 26 /* SQL UNSIGNED INTEGER(32) OTS UINT32 */ +#define OCI_TYPECODE_OCTET 245 /* SQL ??? OTS OCTET */ +#define OCI_TYPECODE_SMALLINT 246 /* SQL SMALLINT OTS SMALLINT */ +#define OCI_TYPECODE_INTEGER SQLT_INT /* SQL INTEGER OTS INTEGER */ +#define OCI_TYPECODE_RAW SQLT_LVB /* SQL RAW(N) OTS RAW(N) */ +#define OCI_TYPECODE_PTR 32 /* SQL POINTER OTS POINTER */ +#define OCI_TYPECODE_VARCHAR2 SQLT_VCS + /* SQL VARCHAR2(N) OTS SQL_VARCHAR2(N) */ +#define OCI_TYPECODE_CHAR SQLT_AFC /* SQL CHAR(N) OTS SQL_CHAR(N) */ +#define OCI_TYPECODE_VARCHAR SQLT_CHR + /* SQL VARCHAR(N) OTS SQL_VARCHAR(N) */ +#define OCI_TYPECODE_MLSLABEL SQLT_LAB /* OTS MLSLABEL */ +#define OCI_TYPECODE_VARRAY 247 /* SQL VARRAY OTS PAGED VARRAY */ +#define OCI_TYPECODE_TABLE 248 /* SQL TABLE OTS MULTISET */ +#define OCI_TYPECODE_OBJECT SQLT_NTY /* SQL/OTS NAMED OBJECT TYPE */ +#define OCI_TYPECODE_OPAQUE 58 /* SQL/OTS Opaque Types */ +#define OCI_TYPECODE_NAMEDCOLLECTION SQLT_NCO + /* SQL/OTS NAMED COLLECTION TYPE */ +#define OCI_TYPECODE_BLOB SQLT_BLOB /* SQL/OTS BINARY LARGE OBJECT */ +#define OCI_TYPECODE_BFILE SQLT_BFILE /* SQL/OTS BINARY FILE OBJECT */ +#define OCI_TYPECODE_CLOB SQLT_CLOB /* SQL/OTS CHARACTER LARGE OBJECT */ +#define OCI_TYPECODE_CFILE SQLT_CFILE /* SQL/OTS CHARACTER FILE OBJECT */ + +/* the following are ANSI datetime datatypes added in 8.1 */ +#define OCI_TYPECODE_TIME SQLT_TIME /* SQL/OTS TIME */ +#define OCI_TYPECODE_TIME_TZ SQLT_TIME_TZ /* SQL/OTS TIME_TZ */ +#define OCI_TYPECODE_TIMESTAMP SQLT_TIMESTAMP /* SQL/OTS TIMESTAMP */ +#define OCI_TYPECODE_TIMESTAMP_TZ SQLT_TIMESTAMP_TZ /* SQL/OTS TIMESTAMP_TZ */ + +#define OCI_TYPECODE_TIMESTAMP_LTZ SQLT_TIMESTAMP_LTZ /* TIMESTAMP_LTZ */ + +#define OCI_TYPECODE_INTERVAL_YM SQLT_INTERVAL_YM /* SQL/OTS INTRVL YR-MON */ +#define OCI_TYPECODE_INTERVAL_DS SQLT_INTERVAL_DS /* SQL/OTS INTRVL DAY-SEC */ +#define OCI_TYPECODE_UROWID SQLT_RDD /* Urowid type */ + + +#define OCI_TYPECODE_OTMFIRST 228 /* first Open Type Manager typecode */ +#define OCI_TYPECODE_OTMLAST 320 /* last OTM typecode */ +#define OCI_TYPECODE_SYSFIRST 228 /* first OTM system type (internal) */ +#define OCI_TYPECODE_SYSLAST 235 /* last OTM system type (internal) */ +#define OCI_TYPECODE_PLS_INTEGER 266 /* type code for PLS_INTEGER */ + +/* the following are PL/SQL-only internal. They should not be used */ +#define OCI_TYPECODE_ITABLE SQLT_TAB /* PLSQL indexed table */ +#define OCI_TYPECODE_RECORD SQLT_REC /* PLSQL record */ +#define OCI_TYPECODE_BOOLEAN SQLT_BOL /* PLSQL boolean */ + +/* NOTE : The following NCHAR related codes are just short forms for saying + OCI_TYPECODE_VARCHAR2 with a charset form of SQLCS_NCHAR. These codes are + intended for use in the OCIAnyData API only and nowhere else. */ +#define OCI_TYPECODE_NCHAR 286 +#define OCI_TYPECODE_NVARCHAR2 287 +#define OCI_TYPECODE_NCLOB 288 + + +/* To indicate absence of typecode being specified */ +#define OCI_TYPECODE_NONE 0 +/* To indicate error has to be taken from error handle - reserved for + sqlplus use */ +#define OCI_TYPECODE_ERRHP 283 + +/* The OCITypeCode type is interchangeable with the existing SQLT type + which is a ub2 */ +typedef ub2 OCITypeCode; + + +/*----------------------- GET OPTIONS FOR TDO ------------------------------*/ + +enum OCITypeGetOpt +{ + OCI_TYPEGET_HEADER, + /* load only the header portion of the TDO when getting type */ + OCI_TYPEGET_ALL /* load all attribute and method descriptors as well */ +}; +typedef enum OCITypeGetOpt OCITypeGetOpt; + +/* + * OCITypeGetOpt + * + * This is the flag passed to OCIGetTypeArray() to indicate how the TDO is + * going to be loaded into the object cache. + * OCI_TYPEGET_HEADER implies that only the header portion is to be loaded + * initially, with the rest loaded in on a 'lazy' basis. Only the header is + * needed for PL/SQL and OCI operations. OCI_TYPEGET_ALL implies that ALL + * the attributes and methods belonging to a TDO will be loaded into the + * object cache in one round trip. Hence it will take much longer to execute, + * but will ensure that no more loading needs to be done when pinning ADOs + * etc. This is only needed if your code needs to examine and manipulate + * attribute and method information. + * + * The default is OCI_TYPEGET_HEADER. + */ + + +/*------------------------ TYPE ENCAPSULTATION LEVEL ------------------------*/ + +enum OCITypeEncap +{ + /* 0 = uninitialized */ + OCI_TYPEENCAP_PRIVATE, /* private: only internally visible */ + OCI_TYPEENCAP_PUBLIC /* public: visible to both internally and externally */ +}; +typedef enum OCITypeEncap OCITypeEncap; +/* + * OCITypeEncap - OCI Encapsulation Level + */ + + +/*---------------------------- TYPE METHOD FLAGS ----------------------------*/ + +enum OCITypeMethodFlag +{ + OCI_TYPEMETHOD_INLINE = 0x0001, /* inline */ + OCI_TYPEMETHOD_CONSTANT = 0x0002, /* constant */ + OCI_TYPEMETHOD_VIRTUAL = 0x0004, /* virtual */ + OCI_TYPEMETHOD_CONSTRUCTOR = 0x0008, /* constructor */ + OCI_TYPEMETHOD_DESTRUCTOR = 0x0010, /* destructor */ + OCI_TYPEMETHOD_OPERATOR = 0x0020, /* operator */ + OCI_TYPEMETHOD_SELFISH = 0x0040, /* selfish method (generic otherwise) */ + + OCI_TYPEMETHOD_MAP = 0x0080, /* map (relative ordering) */ + OCI_TYPEMETHOD_ORDER = 0x0100, /* order (relative ordering) */ + /* OCI_TYPEMETHOD_MAP and OCI_TYPEMETHOD_ORDER are mutually exclusive */ + + OCI_TYPEMETHOD_RNDS= 0x0200, /* Read no Data State (default) */ + OCI_TYPEMETHOD_WNDS= 0x0400, /* Write no Data State */ + OCI_TYPEMETHOD_RNPS= 0x0800, /* Read no Process State */ + OCI_TYPEMETHOD_WNPS= 0x1000, /* Write no Process State */ + OCI_TYPEMETHOD_ABSTRACT = 0x2000, /* abstract (not instantiable) method */ + OCI_TYPEMETHOD_OVERRIDING = 0x4000, /* overriding method */ + OCI_TYPEMETHOD_PIPELINED = 0x8000 /* method is pipelined */ +}; +typedef enum OCITypeMethodFlag OCITypeMethodFlag; + +/* macros to test the type method flags */ +#define OCI_METHOD_IS_INLINE(flag) bit((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_METHOD_IS_CONSTANT(flag) bit((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_METHOD_IS_VIRTUAL(flag) bit((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_METHOD_IS_CONSTRUCTOR(flag) bit((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_METHOD_IS_DESTRUCTOR(flag) bit((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_METHOD_IS_OPERATOR(flag) bit((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_METHOD_IS_SELFISH(flag) bit((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_METHOD_IS_MAP(flag) bit((flag), OCI_TYPEMETHOD_MAP) +#define OCI_METHOD_IS_ORDER(flag) bit((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_METHOD_IS_RNDS(flag) bit((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_METHOD_IS_WNDS(flag) bit((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_METHOD_IS_RNPS(flag) bit((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_METHOD_IS_WNPS(flag) bit((flag), OCI_TYPEMETHOD_WNPS) +#define OCI_METHOD_IS_ABSTRACT(flag) bit((flag), OCI_TYPEMETHOD_ABSTRACT) +#define OCI_METHOD_IS_OVERRIDING(flag) bit((flag), OCI_TYPEMETHOD_OVERRIDING) +#define OCI_METHOD_IS_PIPELINED(flag) bit((flag), OCI_TYPEMETHOD_PIPELINED) + +#define OCI_TYPEMETHOD_IS_INLINE(flag) bit((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_TYPEMETHOD_IS_CONSTANT(flag) bit((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_TYPEMETHOD_IS_VIRTUAL(flag) bit((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_TYPEMETHOD_IS_CONSTRUCTOR(flag) \ + bit((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_TYPEMETHOD_IS_DESTRUCTOR(flag) \ + bit((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_TYPEMETHOD_IS_OPERATOR(flag) bit((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_TYPEMETHOD_IS_SELFISH(flag) bit((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_TYPEMETHOD_IS_MAP(flag) bit((flag), OCI_TYPEMETHOD_MAP) +#define OCI_TYPEMETHOD_IS_ORDER(flag) bit((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_TYPEMETHOD_IS_RNDS(flag) bit((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_TYPEMETHOD_IS_WNDS(flag) bit((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_TYPEMETHOD_IS_RNPS(flag) bit((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_TYPEMETHOD_IS_WNPS(flag) bit((flag), OCI_TYPEMETHOD_WNPS) +#define OCI_TYPEMETHOD_IS_ABSTRACT(flag) bit((flag), OCI_TYPEMETHOD_ABSTRACT) +#define OCI_TYPEMETHOD_IS_OVERRIDING(flag) \ + bit((flag), OCI_TYPEMETHOD_OVERRIDING) +#define OCI_TYPEMETHOD_IS_PIPELINED(flag) bit((flag), OCI_TYPEMETHOD_PIPELINED) + +/* macros to set the type method flags */ +#define OCI_TYPEMETHOD_SET_INLINE(flag) bis((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_TYPEMETHOD_SET_CONSTANT(flag) bis((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_TYPEMETHOD_SET_VIRTUAL(flag) bis((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_TYPEMETHOD_SET_CONSTRUCTOR(flag) \ + bis((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_TYPEMETHOD_SET_DESTRUCTOR(flag) \ + bis((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_TYPEMETHOD_SET_OPERATOR(flag) bis((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_TYPEMETHOD_SET_SELFISH(flag) bis((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_TYPEMETHOD_SET_MAP(flag) bis((flag), OCI_TYPEMETHOD_MAP) +#define OCI_TYPEMETHOD_SET_ORDER(flag) bis((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_TYPEMETHOD_SET_RNDS(flag) bis((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_TYPEMETHOD_SET_WNDS(flag) bis((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_TYPEMETHOD_SET_RNPS(flag) bis((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_TYPEMETHOD_SET_WNPS(flag) bis((flag), OCI_TYPEMETHOD_WNPS) + +/* macros to clear the type method flags */ +#define OCI_TYPEMETHOD_CLEAR_INLINE(flag) bic((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_TYPEMETHOD_CLEAR_CONSTANT(flag) \ + bic((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_TYPEMETHOD_CLEAR_VIRTUAL(flag) bic((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_TYPEMETHOD_CLEAR_CONSTRUCTOR(flag) \ + bic((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_TYPEMETHOD_CLEAR_DESTRUCTOR(flag) \ + bic((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_TYPEMETHOD_CLEAR_OPERATOR(flag) \ + bic((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_TYPEMETHOD_CLEAR_SELFISH(flag) bic((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_TYPEMETHOD_CLEAR_MAP(flag) bic((flag), OCI_TYPEMETHOD_MAP) +#define OCI_TYPEMETHOD_CLEAR_ORDER(flag) bic((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_TYPEMETHOD_CLEAR_RNDS(flag) bic((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_TYPEMETHOD_CLEAR_WNDS(flag) bic((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_TYPEMETHOD_CLEAR_RNPS(flag) bic((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_TYPEMETHOD_CLEAR_WNPS(flag) bic((flag), OCI_TYPEMETHOD_WNPS) + +/*--------------------------- TYPE PARAMETER MODE ---------------------------*/ + +enum OCITypeParamMode +{ + /* PL/SQL starts this from 0 */ + OCI_TYPEPARAM_IN = 0, /* in */ + OCI_TYPEPARAM_OUT, /* out */ + OCI_TYPEPARAM_INOUT, /* in-out */ + OCI_TYPEPARAM_BYREF, /* call by reference (implicitly in-out) */ + OCI_TYPEPARAM_OUTNCPY, /* OUT with NOCOPY modifier */ + OCI_TYPEPARAM_INOUTNCPY /* IN OUT with NOCOPY modifier */ +}; +typedef enum OCITypeParamMode OCITypeParamMode; + + +/*-------------------------------- DEFAULTS ---------------------------------*/ + +/* default binary and decimal precision and scale */ + +#define OCI_NUMBER_DEFAULTPREC ((ub1)0) /* no precision specified */ +#define OCI_NUMBER_DEFAULTSCALE ((sb1)MAXSB1MINVAL) + /* no binary/decimal scale specified */ + +/* default maximum length for varrays and vstrings (used in sql.bsq) */ + +#define OCI_VARRAY_MAXSIZE 4000 + /* default maximum number of elements for a varray */ +#define OCI_STRING_MAXLEN 4000 /* default maximum length of a vstring */ + +/*---------------------------------------------------------------------------*/ +/* This set of macro is used only in beta2. They should be removed as soon as + * PLSQL has made the changes of not using these macros. + */ + +/* Special duration for allocating memory only. No instance can be allocated + * given these durations. + */ +#define OCICoherency OCIRefreshOpt +#define OCI_COHERENCY_NONE (OCIRefreshOpt)2 +#define OCI_COHERENCY_NULL (OCIRefreshOpt)4 +#define OCI_COHERENCY_ALWAYS (OCIRefreshOpt)5 + +#endif /* ORO_ORACLE */ + diff --git a/OCI/include/ort.h b/OCI/include/ort.h new file mode 100644 index 0000000..9562f2e --- /dev/null +++ b/OCI/include/ort.h @@ -0,0 +1,2594 @@ +/* @(#)ort.h 1.44 95/07/07 */ + +/* Copyright (c) 1994, 2005, Oracle. All rights reserved. */ + +/* + NAME + + ORT - ORacle's external open Type interface to the open type manager (OTM) + + DESCRIPTION + + The open type manager interface includes dynamic type operations to + create, delete, update, and access types. See the "Functional + Specification for Oracle Object Call Interface (Objects Project), + Version 1.0" for a user level description of the OTM. For a more + detailed description, see the "Component Document for the Open Type + Manager, Version 1.0". + + NOTE: MOST Of the functions in this header file are being desupported. + Please use the OCIDescribeAny interface as described in oci.h + instead. + The OCIType, OCITypeElem, OCITypeMethod abstract types continue + to be supported. The only two functions that remain to be documented + are OCITypeArrayByName and OCITypeArrayByRef. + All obsolete types/functions are marked accordingly below. + + RELATED DOCUMENTS + + For the functional specification for the OTM, see: + [1] Kotsovolos, Susan, "Functional Specification for Oracle Object + Call Interface (Objects Project), Version 1.0", Oracle + Corporation, February 1995. + For the internal design of the OTM, see the following: + [2] Kotsovolos, Susan, "Component Document for the Open Type Manager", + Oracle Corporation, November 1994. + [3] Kotsovolos, Susan, "Design for The Open Type Manager, Oracle + Object Management Subsystem Version 1.0", Oracle Corporation, + March 1994. + [4] Kotsovolos, Susan and Tin A. Nguyen, "The Open Type Manager", + Oracle Corporation, March 1994. + [5] Kotsovolos, Susan and Tin A. Nguyen, "Schema Evolution", + Oracle Corporation, March 1994. + For a description of the types the OTM must support, see: + [6] Nguyen, Tin A., "The Open Type System", Oracle Corporation, + February 1994. + + INSPECTION STATUS + + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + + Review date: + Review status: + Reviewers: + + + **** ALL OBSOLETE FUNCTIONS/TYPES ARE MARKED ACCORDINGLY *** + + EXPORT FUNCTIONS + + None + + PUBLIC DATA STRUCTURES + + OCIType - type descriptor in the object cache + OCITypeElem - type element descriptor in the object cache + (used for attributes and paramters) + OCITypeCode - Open Type System type code. + OCITypeMethod - method descriptor in the object cache + OCITypeParamMode - parameter modes (ie. IN, IN-OUT etc) + + PUBLIC FUNCTIONS + + ITERATOR (for OCITypeAttrNext and OCITypeMethodNext) + + OCITypeIterNew - ** OBSOLETE ** Create new instance of an iteraton. + OCITypeIterSet - ** OBSOLETE ** Initialize iterator. + OCITypeIterFree - ** OBSOLETE ** Free instance of iterator. + + TYPE GET + + OCITypeByName - ** OBSOLETE ** Get a type by name. + OCITypeArrayByName - Get an array of types by their names. + OCITypeByRef - ** OBSOLETE ** Get a type by its CREF. + OCITypeArrayByRef - Get an array of types by their CREFs. + + TYPE ACCESSORS + + OCITypeName - ** OBSOLETE ** OCI Get a type's name. + OCITypeSchema - ** OBSOLETE ** OCI Get a type's schema name. + OCITypeTypeCode - ** OBSOLETE ** OCI Get a type's type code. + OCITypeVersion - ** OBSOLETE ** OCI Get a Type's user-readable Version. + OCITypeAttrs - ** OBSOLETE ** OCI Get a Type's Number of Attributes. + OCITypeMethods - ** OBSOLETE ** OCI Get a Type's Number of Methods. + + TYPE ELEMENT ACCESSORS (they represent attributes/parameters/results) + + OCITypeElemName - ** OBSOLETE ** Get a type element's (only for + attributes) name. + OCITypeElemType - ** OBSOLETE ** Get a type element's type + descriptor. + OCITypeElemTypeCode - ** OBSOLETE ** Get a type element's typecode. + OCITypeElemParameterizedType - ** OBSOLETE ** Get a type element's + parameterized type's type descriptor. + OCITypeElemNumPrec - ** OBSOLETE ** Get a number's precision. + OCITypeElemNumScale - ** OBSOLETE ** Get a decimal or oracle Number's + Scale + OCITypeElemCharSetID - ** OBSOLETE ** Get a fixed or variable length + string's character set ID. + OCITypeElemCharSetForm - ** OBSOLETE ** Get a fixed or variable length + string's character set form (how + character set information has + been specified). + OCITypeElemLength - ** OBSOLETE ** Get a raw, fixed or variable + length string's length. + OCITypeElemParamMode - ** OBSOLETE ** Get element's parameter's mode + (only valid for parameter). + OCITypeElemDefaultValue - ** OBSOLETE ** Get element's Default Value. + + ATTRIBUTE ACCESSORS + + OCITypeAttrByName - ** OBSOLETE ** Get an Attribute by Name. + OCITypeAttrNext - ** OBSOLETE ** Get an Attribute by Iteration. + + COLLECTION ACCESSORS + + OCITypeCollTypeCode - ** OBSOLETE ** Get a named collection's typecode. + OCITypeCollElem - ** OBSOLETE ** Get a named collection's element's + type element information. + OCITypeCollSize - ** OBSOLETE ** Get a named collection's size in + number of elements. + + METHOD ACCESSORS + + OCITypeMethodOverload - ** OBSOLETE ** Get number of overloaded methods + with the given method name. + (no direct equivalent for + OCIDescribe interface) + OCITypeMethodByName - ** OBSOLETE ** Get one or more methods by name. + OCITypeMethodNext - ** OBSOLETE ** Iterate to the next method to + retrieve. + OCITypeMethodName - ** OBSOLETE ** Get method's name. + OCITypeMethodEncap - ** OBSOLETE ** Get method's encapsulation level. + OCITypeMethodFlags - ** OBSOLETE ** et method's flags. + OCITypeMethodMap - ** OBSOLETE ** Get type's map function. + OCITypeMethodOrder - ** OBSOLETE ** Get type's order function. + OCITypeMethodParams - ** OBSOLETE ** Get a method's number of + parameters. + + RESULT ACCESSORS + + OCITypeResult - ** OBSOLETE ** OCI Get a method's Result. + + See also ATTRIBUTE/PARAMETER/RESULT TYPE ACCESSORS. + + PARAMETER ACCESSORS + + OCITypeParamByPos - ** OBSOLETE ** Get a Parameter in a method By + Position. + OCITypeParamByName - ** OBSOLETE ** Get a Parameter in a method By Name. + OCITypeParamPos - ** OBSOLETE ** Get a Parameter's PoSition in a + method. + + CALL GRAPHS: + + Only type accessors are supported for 8.0. + ** OBSOLETE ** please use OCIDescribe interface + + TYPE ACCESSOR EXAMPLE + + CREATE TYPE CAR + ( + name vstring, + age number, + number car_age; /o Oracle number o/ + weight car_weight; /o abstract type o/ + + PUBLIC: + + /o methods o/ + car(orlvs a_name, number an_age, WEIGHT a_weight); + ~car(); + inline number get_age() const; + + /o relative ordering (map) functions o/ + number car_map + ); + + /o the following code accesses the type created above o/ + + ub1 meth_flags; + ub4 i, j; + ub4 text_len, position; + ub4 count; + ub4 length; + OCITypeCode typecode; + OCIRef *attr_ref; + OCIRef *param_ref; + OCIType *tdo, new_tdo, final_tdo; + OCITypeElem *elem; + OCITypeIter *iterator_ort; + oratext (*names)[]; + ub4 lengths[]; + ub4 *positions; + oratext *name; + oratext name_buffer[M_IDEN]; + + /o initialize the references o/ + DISCARD orlrini(env, err, (dvoid *)&attr_ref); + DISCARD orlrini(env, err, (dvoid *)¶m_ref); + + /o ----------------- GET INFORMATION ABOUT A TYPE ----------------- o/ + + /o start a transaction o/ + + /o Pin the type until the end of the transaction. Pinning the type is + o required before using any type accessors. + o/ + if (OCITypeByName(env, err, svc, (oratext *)0, 0, "CAR", strlen("CAR"), + OCI_DURATION_TRANS, &car_ref, &car_tdo) != OCI_SUCCESS) + /o error o/ ; + + /o get the type's name o/ + if (!memcmp(OCITypeName(env, err, car_tdo, &text_len), "person", + text_len)) + /o do something o/ ; + + /o get the type's schema name o/ + if (!memcmp(OCITypeSchema(env, err, car_tdo, &text_len), "john", + text_len)) + /o do something o/ ; + + /o get the type code of the type o/ + if (OCITypeTypeCode(env, err, car_tdo) == OCI_TYPECODE_ADT) + /o do something o/ ; + + /o get the type version o/ + if (!memcmp(OCITypeVersion(env, err, car_tdo, &text_len), "1", text_len)) + /o do something o/ ; + + /o ------- GET FLATTENED POSITION OF AN ATTRIBUTES IN A TYPE ------- o/ + + names = malloc(sizeof(oratext *) * 2); + names[0] = malloc(strlen("car_weight")); + names[1] = malloc(strlen("ounces")); + memcpy(names[0], "car_weight", strlen("car_weight")); + memcpy(names[1], "ounces", strlen("ounces")); + + lengths = malloc(sizeof(ub4) * 2); + lengths[0] = strlen("car_weight"); + lengths[1] = strlen("ounces"); + + /o ---------- GET IMMEDIATE ATTRIBUTES IN A TYPE ---------- o/ + + /o loop through all attributes in the type with iterator o/ + if (OCITypeIterNew(env, err, car_tdo, &iterator_ort) != OCI_SUCCESS) + /o do something o/ + + while (OCITypeAttrNext(env, err, iterator_ort, &ado) != OCI_NO_DATA) + { + /o get the attribute's name o/ + if (!memcmp(OCITypeElemName(env, err, ado, &text_len), + "tiger", text_len)) + /o do something o/ ; + + /o get the attribute's type descriptor o/ + if (OCITypeElemType(env, err, ado, &tdo) != OCI_SUCCESS) + /o error o/ ; + + /o get the attribute's type code o/ + typecode = OCITypeElemTypeCode(env, err, ado); + + switch (typecode) + { + /o scalar types o/ + case OCI_TYPECODE_DATE: /o date o/ + case OCI_TYPECODE_SIGNED8: /o byte o/ + case OCI_TYPECODE_SIGNED16: /o short o/ + case OCI_TYPECODE_UNSIGNED8: /o unsigned byte o/ + case OCI_TYPECODE_UNSIGNED16: /o unsigned short o/ + case OCI_TYPECODE_OCTET: /o octet o/ + case OCI_TYPECODE_TABLE: /o nested table o/ + case OCI_TYPECODE_CLOB: /o character lob o/ + case OCI_TYPECODE_BLOB: /o binary lob o/ + case OCI_TYPECODE_CFILE: /o character file object o/ + case OCI_TYPECODE_BFILE: /o binary file object o/ + + /o do something o/ + break; + + /o number types o/ + case OCI_TYPECODE_NUMBER: /o oracle number o/ + case OCI_TYPECODE_DECIMAL: /o decimal o/ + { + /o get the scale of the number o/ + if (OCITypeElemNumScale(env, err, ado) == 3) + /o do something o/ ; + } + /o fall through to get the precision o/ + + case OCI_TYPECODE_FLOAT: /o float o/ + case OCI_TYPECODE_SIGNED32: /o long o/ + case OCI_TYPECODE_UNSIGNED32: /o unsigned long o/ + case OCI_TYPECODE_REAL: /o real o/ + case OCI_TYPECODE_DOUBLE: /o double o/ + { + /o get the precision of the number o/ + if (OCITypeElemNumPrec(env, err, ado) == 2) + /o do something o/ ; + } + break; + + /o string types o/ + case OCI_TYPECODE_CHAR: /o fixed length string o/ + case OCI_TYPECODE_VARCHAR2: /o variable length string o/ + case OCI_TYPECODE_RAW: /o raw o/ + { + /o get the length of the fixed or variable length string o/ + if (OCITypeElemLength(env, err, ado) < 100) + /o do something o/ + } + break; + + /o parameterized types o/ + case OCI_TYPECODE_REF: /o reference o/ + case OCI_TYPECODE_PTR: /o pointer o/ + { + /o get the type stored in the parameterized type o/ + if (OCITypeElemParameterizedType(env, err, ado, &tdo) + != OCI_SUCCESS) + /o error o/ ; + + /o do something o/ + if (OCI_TYPEELEM_IS_REF(OCITypeElemFlags(env, err, ado)))... + } + break; + + /o domain type o/ + case OCI_TYPECODE_NAMEDCOLLECTION: + switch (OCITypeCollTypeCode(env, err, tdo)) + { + case OCI_TYPECODE_VARRAY: /o variable array o/ + ub4 num_elems; + OCIType *element_type; + + /o get the number of elements in the farray or the maximum number + o of elements in the varray. + o/ + OCITypeCollSize(env, err, tdo, &num_elems); + + /o get the type of the array o/ + OCITypeElemType(env, err, tdo, &element_type); + } + break; + + case OCI_TYPECODE_TABLE: /o multiset o/ + { + OCIType *table_type; + + /o get the type of the multiset o/ + OCITypeElemType(env, err, tdo, &table_type); + + /o do something o/ + } + } + + /o abstract type o/ + case OCI_TYPECODE_ADT: /o abstract data type o/ + { + /o get the adt information o/ + if (OCITypeElemType(env, err, ado, &tdo) != OCI_SUCCESS) + /o error o/ ; + + /o do something o/ + } + break; + + default: + DISCARD printf("Error: invalid type code\n"); + + } /o end of typecode switch o/ + + } /o end of loop through all attributes in a type o/ + + + /o ------------ GET THE IMMEDIATE METHODS OF A TYPE ------------ o/ + + /o loop through all methods in the type by reusing iterator o/ + if (OCITypeIterSet(env, err, car_tdo, iterator_ort) != OCI_SUCCESS) + /o do something o/ + + while (OCITypeMethodNext(env, err, iterator_ort) != OCI_NO_DATA) + { + /o get the method's name o/ + if (!memcmp(OCITypeMethodName(env, err, mdo, &text_len), "car", + text_len)) + /o do something o/ ; + + /o get the method's encapsulation o/ + if (OCITypeMethodEncap(env, err, mdo) == OCI_TYPEENCAP_PUBLIC) + /o do something o/ ; + + /o get the method's flags o/ + meth_flags = OCITypeMethodFlags(env, err, mdo); + if (meth_flags & OCI_TYPEMETHOD_VIRTUAL) + /o do something o/ ; + + + /o ------------ GET THE PARAMETERS IN A METHOD ------------ o/ + + /o loop through all parameters in the method o/ + count = OCITypeMethodParams(env, err, mdo); + for (j = 1; j <= count; j++) + { + /o get the parameter information by position o/ + if (OCITypeParamByPos(env, err, mdo, i, &elem) != OCI_SUCCESS) + /o error o/ ; + + /o get the parameter's name o/ + if (!memcmp(OCITypeElemName(env, err, elem, &text_len), "an_age", + text_len)) + /o do something o/ ; + + /o get the parameter's mode o/ + if (OCITypeElemMode(env, err, elem) == OCI_PARAM_OUT) + /o do something o/ ; + + /o get the parameter's required flag o/ + if (ortgprq(env, err, elem)) + /o do something o/ ; + } + } + + /o get a method by name o/ + if (OCITypeMethodByName(env, err, car_tdo, "car_constructor", + strlen("car_constructor"), NULLP(OCIRef), &mdo) + != OCI_SUCCESS) + /o error o/ ; + + /o get a parameter in a method by name o/ + if (OCITypeParamByName(env, err, mdo, "an_age", strlen("an_age"), &elem) + != OCI_SUCCESS) + /o error o/ ; + + /o get a parameter's typecode o/ + typecode = OCITypeElemTypeCode(env, err, elem); + + /o get a parameter's type object o/ + if (OCITypeElemType(env, err, elem, &tdo)) != OCI_SUCCESS) + /o error o/ ; + + /o get a parameter's position in a method o/ + if (ortgpps(env, err, mdo, "an_age", strlen("an_age"), + &position, NULLP(OCIRef), NULLP(OCITypeElem)) != OCI_SUCCESS) + /o error o/ ; + + /o ------------ GET THE METHOD's RESULT ------------ o/ + + /o get a method by name o/ + if (OCITypeMethodByName(env, err, car_tdo, "get_age", strlen("get_age"), + &mdo) != OCI_SUCCESS) + /o error o/ ; + + /o get the typecode of the method's result o/ + typecode = OCITypeElemTypeCode(env, err, mdo); + + + /o ----------------- END ---------------- o/ + + /o free the references implicitly allocated o/ + DISCARD orlrfre(env, err, (dvoid *)&attr_ref); + DISCARD orlrfre(env, err, (dvoid *)¶m_ref); + + NOTES + + MODIFIED + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + aahluwal 06/03/02 - bug 2360115 + skabraha 04/16/02 - fix compiler warnings + rkasamse 03/02/01 - do not use iterator : keyword in MSVB + bpalaval 02/09/01 - Change text to oratext. + rxgovind 01/31/00 - add OCIType interfaces for transient types + whe 09/01/99 - 976457:check __cplusplus for C++ code + cxcheng 05/06/97 - make OCI_TYPE?? test macros return either 1 or 0 + cxcheng 04/22/97 - add comment on desupporting OCIType functions + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/26/97 - fix lint problem with oro names + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + cxcheng 01/15/97 - change prototype of OCITypeElemParameterizedType() + cxcheng 01/03/97 - replace bit in OCI_TYPEPARAM_IS_REQUIRED with bitwis + cxcheng 12/31/96 - replace OCI_PARAM_IS_REQUIRED with OCI_TYPEPARAM_IS_ + cxcheng 12/09/96 - add prototype for OCITypeElemExtTypeCode and OCIType + cxcheng 11/25/96 - add schema name parameter to OCITypeVTInsert() + cxcheng 11/20/96 - fix prototype for OCITypeByName() + cxcheng 11/11/96 - fix prototype for OCITypeByName() + cxcheng 11/05/96 - remove OCITypeElemExtTypeCode and OCITypeCollExtType + dchatter 10/28/96 - change ortgatyp to be OCITypeArrayByName + cxcheng 10/25/96 - fix problem with ortgatyp at end + cxcheng 10/22/96 - add OCITypeByRef and OCITypeArrayByRef + cxcheng 10/20/96 - remove ortgtyp() from #define section at end + cxcheng 10/18/96 - rename OCITypeGetArray to OCITypeArrayByName + cxcheng 10/17/96 - final change to prototype for OCI_TYPEPARAM_IS_REQUI + cxcheng 10/15/96 - rename OCIEncapLevel and OCIMethodFlag + cxcheng 10/14/96 - change prototype of OCITypeResult + mluong 10/11/96 - fix compile error + jwijaya 10/10/96 - fix bug on OCI_PARAM_IS_REQUIRED + cxcheng 10/09/96 - more lint and link fixes + cxcheng 10/08/96 - more lint fixes + cxcheng 10/07/96 - more changes + cxcheng 10/04/96 - replace short names with long names + cxcheng 10/01/96 - change to long names for readability + cxcheng 09/27/96 - rename ortgatyp() to ortgtya() for lint + cxcheng 09/20/96 - add ortgatyp() for array get type + cxcheng 09/18/96 - add array pin and iterator functions + cxcheng 08/09/96 - add version table calls + cxcheng 07/22/96 - add OCITypeElemType() to top + jwijaya 07/03/96 - add ANSI prototypes + cxcheng 06/28/96 - add OCITypeElemCharSetForm() + cxcheng 06/26/96 - fix comment on OCITypeParamByPos()/ortgpps() + cxcheng 06/18/96 - fix comments on OCITypeResult() + cxcheng 06/17/96 - improve comments + skrishna 06/03/96 - change OCITypeCollElem() prototype + vkrishna 05/29/96 - replace OROTCFAR with OROTCCAR + cxcheng 05/28/96 - fix comments, remove non-beta1 functions + cxcheng 05/02/96 - fix prototype bugs + cxcheng 04/29/96 - rename OCITypeElemm() to ortanct() + cxcheng 04/26/96 - add ortgrbp and ortftyi, + fix comments and examples + cxcheng 04/22/96 - big merge to main branch + cxcheng 04/17/96 - fix syntax + cxcheng 04/08/96 - change prototype to ortaty() + skrishna 04/08/96 - change ort*() to take OCIEnv* and OCIError* instead + of oroenv* + cxcheng 03/28/96 - add ortslob(), change ortsstr() prototype + cxcheng 03/13/96 - change alter type interface + cxcheng 03/11/96 - ORT interface changes + cxcheng 02/27/96 - correct comments + jboonleu 02/09/96 - rename oroopd to OCIDuration + cxcheng 01/19/96 - change ORTCTYVAL to ORTCTYEMB for embedded ADT + cxcheng 02/14/96 - add more comments + jboonleu 02/09/96 - rename oroopd to OCIDuration + cxcheng 02/07/96 - fix comments and examples + cxcheng 01/19/96 - new ORT interface without korfc's + cxcheng 01/08/96 - consolidate collection functions + cxcheng 12/14/95 - remove obsolete ortgcol() and ortrelease() + jweisz 12/12/95 - merge screwup: ortdth twice + cxcheng 12/05/95 - change multiset interface for new standard + skotsovo 12/01/95 - merge from /vobs/rdbms/public/ort.h@@/main/ + st_rdbms_big_dev/st_rdbms_obj/ + st_rdbms_jwijaya_variable_ref + cxcheng 11/13/95 - add ortaty()/orteaty() + cxcheng 11/13/95 - add new collection type accessors + skotsovo 10/30/95 - add 'oid' type b/c extent type uses it. + skotsovo 10/24/95 - update according to new variable length ref + cxcheng 10/05/95 - add null support, change prototypes to calls + cxcheng 10/03/95 - add OCITypeMethodOrder() to get ORDER method + cxcheng 09/28/95 - add OCITypeElemm() for collection types support + skotsovo 06/05/95 - add adt_type parameter to ortsab() + skotsovo 05/10/95 - ifdef'd out ortgafp() + skotsovo 03/07/95 - update interface to only include release 1 + skotsovo 02/22/95 - add multiset accessors + skotsovo 02/09/95 - update according to new ots doc + skotsovo 01/31/95 - add rest of release 1 types + skotsovo 01/24/95 - categorize sint32, double, and real as number types + (with precision and scale) instead of scalar types. + skotsovo 01/12/95 - remove dependency from ortdty interface + skotsovo 01/03/95 - remove orotyp accessors + skotsovo 12/12/94 - update comments + skotsovo 12/05/94 - change OCITypeElemParameterizedTyper interface + skotsovo 10/26/94 - add type version table + skotsovo 10/17/94 - fix ortgafp() comments + skotsovo 10/14/94 - modify ortgafp() parameters + skotsovo 10/14/94 - add examples + skotsovo 10/13/94 - add a few new routines + jwijaya 10/07/94 - add namespace to pin by name + jwijaya 10/02/94 - connection handle -> connection number + skotsovo 09/13/94 - modify example to use updated oririni interface + skotsovo 08/25/94 - change scale to sb1 from sb2 + skotsovo 07/28/94 - add ortbeg() and ortend() + skotsovo 07/14/94 - add decimal type & call graph + skotsovo 06/28/94 - subset by removing miscellaneous functions + skotsovo 06/28/94 - consistently put comments before typedefs + skotsovo 06/27/94 - modify according to new header file template, add + more examples, and change ortcty() to return a + reference to the type + skotsovo 06/24/94 - add functions to get type information from orotyp + skotsovo 06/20/94 - finish modifying according to header template + skotsovo 06/09/94 - modify according to header file template + skotsovo 06/08/94 - replace s.h with oratypes.h + skotsovo 05/24/94 - modify comments & update example + skotsovo 05/23/94 - modify fnt names for create, alter and drop type + skotsovo 05/18/94 - remove ortdme() -- delete a method + skotsovo 05/17/94 - add tdo parameter to all type modifiers + skotsovo 05/11/94 - return text* instead of including it in arglist + skotsovo 11/16/93 - creation + +*/ + +#ifndef ORATYPES +#include +#endif +#ifndef ORO_ORACLE +#include +#endif +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#define ORT_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCITypeArrayByName ortgatyp +#define OCITypeAttrByName ortgabn +#define OCITypeAttrNext ortgabi +#define OCITypeAttrs ortgtna +#define OCITypeByRef ortgtbrf +#define OCITypeCollElem ortgcel +#define OCITypeCollExtTypeCode ortgcsqt +#define OCITypeCollSize ortgcne +#define OCITypeCollTypeCode ortgdttc +#define OCITypeElem ortado +#define OCITypeElemCharSetForm ortgscform +#define OCITypeElemCharSetID ortgscid +#define OCITypeElemDefaultValue ortgpdv +#define OCITypeElemExtTypeCode ortgasqt +#define OCITypeElemLength ortgsl +#define OCITypeElemName ortganm +#define OCITypeElemNumPrec ortgnp +#define OCITypeElemNumScale ortgns +#define OCITypeElemParamMode ortgpmo +#define OCITypeElemParameterizedType ortgpa +#define OCITypeElemType ortgaty +#define OCITypeElemTypeCode ortgatc +#define OCITypeIter ortitr +#define OCITypeIterFree ortifre +#define OCITypeIterNew ortinew +#define OCITypeIterSet ortiset +#define OCITypeMethod ortmdo +#define OCITypeMethodByName ortgmbn +#define OCITypeMethodEncap ortgmen +#define OCITypeMethodFlags ortgmfl +#define OCITypeMethodMap ortgmmap +#define OCITypeMethodName ortgmnm +#define OCITypeMethodNext ortgmbi +#define OCITypeMethodOrder ortgmor +#define OCITypeMethodOverload ortgmno +#define OCITypeMethodParams ortgmnp +#define OCITypeMethods ortgtnm +#define OCITypeName ortgtme +#define OCITypeParamByName ortgpbn +#define OCITypeParamPos ortgpps +#define OCITypeSchema ortgtsch +#define OCITypeTypeCode ortgttc +#define OCITypeVTInit ortvini +#define OCITypeVTInsert ortvins +#define OCITypeVTSelect ortvsel +#define OCITypeVersion ortgtvn + +#endif /* SLSHORTNAME */ + + +/*============================*/ +/* PUBLIC TYPES AND CONSTANTS */ +/*============================*/ + +/*----------------------------- TYPE DESCRIPTION ----------------------------*/ + +/* + * OCIType - OCI Type Description Object + * + * The contents of an 'OCIType' is private/opaque to clients. Clients just + * need to declare and pass 'OCIType' pointers in to the type manage + * functions. + * The pointer points to the type in the object cache. Thus, clients don't + * need to allocate space for this type and must NEVER free the pointer to the + * 'OCIType'. + */ + +typedef struct OCIType OCIType; + +/*------------------------- TYPE ELEMENT DESCRIPTION ------------------------*/ + + +/* + * OCITypeElem - OCI Type Element object + * + * The contents of an 'OCITypeElem' is private/opaque to clients. Clients just + * need to declare and pass 'OCITypeElem' pointers in to the type manager + * functions. + * + * 'OCITypeElem' objects contains type element information such as the numeric + * precision for example, for number objects, and the number of elements for + * arrays. + * They ARE used to describe type attributes, collection elements, + * method parameters, and method results. Hence they are pass in or returned + * by attribute, collection, and method parameter/result accessors. + */ + +typedef struct OCITypeElem OCITypeElem; + + +/*--------------------------- METHOD DESCRIPTION ---------------------------*/ + + +/* + * OCITypeMethod - OCI Method Description object + * + * The contents of an 'OCITypeMethod' is private/opaque to clients. Clients + * just need to declare and pass 'OCITypeMethod' pointers in to the type + * manager functions. + * The pointer points to the method in the object cache. Thus, clients don't + * need to allocate space for this type and must NEVER free the pointer to + * the 'OCITypeMethod'. + */ + +typedef struct OCITypeMethod OCITypeMethod; + + +/*--------------------------- TYPE ACCESS ITERATOR --------------------------*/ + +/* + * OCITypeIter- OCI Type Iterator + * + * The contents of an 'orti' is private/opaque to clients. Clients just + * need to declare and pass 'orti' pointers in to the type manager functions. + * The iterator is used to retreive MDO's and ADO's that belong to the TDO + * one at a time. It needs to be allocated by the 'OCITypeIterNew()' function + * call and deallocated with the 'OCITypeIterFree()' function call. + */ + +typedef struct OCITypeIter OCITypeIter; + + +/*==================*/ +/* PUBLIC FUNCTIONS */ +/*==================*/ + +/*--------------------------------------------------------------------------*/ +/* ITERATOR */ +/*--------------------------------------------------------------------------*/ + +/*-----------------------_- OCITypeIterNew ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeIterNew( OCIEnv *env, OCIError *err, OCIType *tdo, + OCITypeIter **iterator_ort ); + +/* + NAME: OCITypeIterNew - OCI Iterator NEW + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the pinned type in the object cache to + initialize the iterator with + iterator_ort (OUT) - pointer to the pointer to the new iterator created + DESCRIPTION: + Create a new instance of a method/attribute iterator and initalize + it's values. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) error while allocating space for the iterator. +*/ + +/*------------------------ OCITypeIterSet ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeIterSet( OCIEnv *env, OCIError *err, OCIType *tdo, + OCITypeIter *iterator_ort ); + +/* + NAME: OCITypeIterSet - OCI Iterator SET + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the pinned type in the object cache to + initialize the iterator with + iterator_ort (IN/OUT) - pointer to the iterator to set + DESCRIPTION: + Initializes the iterator. This is used to reset the state of the + iterator. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. +*/ + +/*------------------------ OCITypeIterFree ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeIterFree( OCIEnv *env, OCIError *err, OCITypeIter + *iterator_ort ); + +/* + NAME: OCITypeIterFree - OCI Iterator FREe + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + iterator_ort (IN/OUT) - pointer to the iterator to free + DESCRIPTION: + Free space allocated for the iterator. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) error while freeing the iterator, probably bad iterator pointer. +*/ + + +/*--------------------------------------------------------------------------*/ +/* TYPE GET */ +/*--------------------------------------------------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeByName( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + const oratext *schema_name, ub4 s_length, + const oratext *type_name, ub4 t_length, + const oratext *version_name, ub4 v_length, + OCIDuration pin_duration, OCITypeGetOpt get_option, + OCIType **tdo ); +/* + NAME: OCITypeByName - OCI Get the most current version of an existing TYPe + by name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN) - OCI service handle + schema_name (IN, optional) - name of schema associated with the + type. By default, the user's schema name is used. + s_length (IN) - length of the 'schema_name' parameter + type_name (IN) - name of the type to get + t_length (IN) - length of the 'type_name' parameter + version_name (IN, optional) - user readable version of the type. + Pass (oratext *)0 for the most current version. + v_length (IN) - length of version_name in bytes. Should be 0 if + the most current version is to be retrieved. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction). See 'oro.h' for a description of + each option. + get_option (IN) - options for loading the types. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - pointer to the pinned type in the object cache + DESCRIPTION: + Get a pointer to a version of the existing type associated + with schema/type name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) the adt type associated with schema/type name does not exist. + NOTE: + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. +*/ + +sword OCITypeArrayByName( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + ub4 array_len, + const oratext *schema_name[], ub4 s_length[], + const oratext *type_name[], ub4 t_length[], + const oratext *version_name[], ub4 v_length[], + OCIDuration pin_duration, + OCITypeGetOpt get_option, OCIType **tdo ); + +/* + NAME: OCITypeArrayByName - OCI Get array of TYPes by name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN) - OCI service handle + array_len (IN) - number of schema_name/type_name/version_name entries to + be retrieved. + schema_name (IN, optional) - array of schema names associated with the + types to be retrieved. The array must have array_len + elements if specified. + If 0 is supplied, the default schema is assumed, otherwise + it MUST have array_len number of elements. + 0 can be supplied for one or more of the entries to indicate + that the default schema is desired for those entries. + s_length (IN) - array of schema_name lengths with each entry + corresponding to the length of the corresponding schema_name + entry in the schema_name array in bytes. + The array must either have array_len number of elements or + it MUST be 0 if schema_name is not specified. + type_name (IN) - array of the names of the types to retrieve. This + MUST have array_len number of elements. + t_length (IN) - array of the lengths of type names in the type_name + array in bytes. + version_name (IN) - array of the version names of the types to retrieve + corresponding. This can be 0 to indicate retrieval of the + most current versions, or it MUST have array_len number of + elements. + If 0 is supplied, the most current version is assumed, + otherwise it MUST have array_len number of elements. + 0 can be supplied for one or more of the entries to indicate + that the current version is desired for those entries. + v_length (IN) - array of the lengths of version names in the + version_name array in bytes. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction) for the types retreieve. See 'oro.h' for a + description of each option. + get_option (IN) - options for loading the types. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - output array for the pointers to each pinned type in the + object cache. It must have space for array_len pointers. + Use OCIObjectGetObjectRef() to obtain the CREF to each + pinned type descriptor. + DESCRIPTION: + Get pointers to the existing types associated with the schema/type name + array. This is similar to OCITypeByName() except that all the TDO's are + retreived via a single network roundtrip. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) one or more adt types associated with a schema/type name entry + does not exist. +*/ + +sword OCITypeByRef( OCIEnv *env, OCIError *err, + const OCIRef *type_ref, OCIDuration pin_duration, + OCITypeGetOpt get_option, OCIType **tdo ); + +/* + NAME: OCITypeArrayByRef - OCI Get array of TYPes by REF. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + type_ref (IN) - OCIRef * pointing to the particular version of + the type descriptor object to obtain. + The array must have array_len elements if specified. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction) for the type to retreieve. See 'oro.h' for a + description of each option. + get_option (IN) - options for loading the type. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - pointer to the pinned type in the object cache + DESCRIPTION: + Get pointers to the + with the schema/type name array. This is similar to OCITypeByName() + except that all the TDO's are retreived via a single network roundtrip. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) one or more adt types associated with a schema/type name entry + does not exist. +*/ + +sword OCITypeArrayByRef( OCIEnv *env, OCIError *err, + ub4 array_len, const OCIRef **type_ref, + OCIDuration pin_duration, + OCITypeGetOpt get_option, OCIType **tdo ); + +/* + NAME: OCITypeArrayByRef - OCI Get array of TYPes by REF. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + array_len (IN) - number of schema_name/type_name/version_name entries to + be retrieved. + type_ref (IN) - array of OCIRef * pointing to the particular version of + the type descriptor object to obtain. + The array must have array_len elements if specified. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction) for the types retreieve. See 'oro.h' for a + description of each option. + get_option (IN) - options for loading the types. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - output array for the pointers to each pinned type in the + object cache. It must have space for array_len pointers. + Use OCIObjectGetObjectRef() to obtain the CREF to each + pinned type descriptor. + DESCRIPTION: + Get pointers to the + with the schema/type name array. This is similar to OCITypeByName() + except that all the TDO's are retreived via a single network roundtrip. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) one or more adt types associated with a schema/type name entry + does not exist. +*/ + + +/*--------------------------------------------------------------------------*/ +/* TYPE ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*---------------------------- OCITypeName ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeName( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *n_length ); +/* + NAME: OCITypeName - ORT Get a Type's naME. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + n_length (OUT) - length (in bytes) of the returned type name. The + caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'n_length' must point to an allocated ub4. + DESCRIPTION: + Get the name of the type. + RETURNS: + the name of the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------ OCITypeSchema ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeSchema( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *n_length ); +/* + NAME: OCITypeSchema - ORT Get a Type's SCHema name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + n_length (OUT) - length (in bytes) of the returned schema name. The + caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'n_length' must point to an allocated ub4. + DESCRIPTION: + Get the schema name of the type. + RETURNS: + the schema name of the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------ OCITypeTypeCode ---------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeTypeCode( OCIEnv *env, OCIError *err, + const OCIType *tdo ); +/* + NAME: OCITypeTypeCode - OCI Get a Type's Type Code. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the type code of the type. + RETURNS: + The type code of the type. + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*----------------------- OCITypeCollTypeCode -------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeCollTypeCode( OCIEnv *env, OCIError *err, + const OCIType *tdo ); +/* + NAME: OCITypeCollTypeCode - OCI Get a Domain Type's Type Code. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'tdo' MUST point to a named collection type. + DESCRIPTION: + Get the type code of the named collection type. For V8.0, named + collection types can only be variable length arrays and nested tables. + RETURNS: + OCI_TYPECODE_VARRAY for variable length array, and + OCI_TYPECODE_TABLE for nested tables. + NOTES: + The type descriptor, 'tdo', should be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------- OCITypeVersion ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeVersion( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *v_length ); +/* + NAME: OCITypeVersion - OCI Get a Type's user-readable VersioN. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + v_length (OUT) - length (in bytes) of the returned user-readable + version. The caller must allocate space for the ub4 before + calling this routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'v_length' must point to an allocated ub4. + DESCRIPTION: + Get the user-readable version of the type. + RETURNS: + The user-readable version of the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*--------------------------- OCITypeAttrs ---------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeAttrs( OCIEnv *env, OCIError *err, const OCIType *tdo ); +/* + NAME: OCITypeAttrs - OCI Get a Type's Number of Attributes. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the number of attributes in the type. + RETURNS: + The number of attributes in the type. 0 for ALL non-ADTs. + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------- OCITypeMethods ---------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeMethods( OCIEnv *env, OCIError *err, const OCIType *tdo ); +/* + NAME: OCITypeMethods - OCI Get a Type's Number of Methods. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the number of methods in a type. + RETURNS: + The number of methods in the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* TYPE ELEMENT INFORMATION ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeElemName ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeElemName( OCIEnv *env, OCIError *err, + const OCITypeElem *elem, ub4 *n_length ); +/* + NAME: OCITypeElemName - OCI Get an Attribute's NaMe. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + n_length (OUT) - length (in bytes) of the returned attribute name. + The caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'n_length' must point to an allocated ub4. + DESCRIPTION: + Get the name of the attribute. + RETURNS: + the name of the attribute and the length in n_length + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeElemTypeCode ------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeElemTypeCode( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemTypeCode - OCI Get an Attribute's TypeCode. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the typecode of an attribute's type. + RETURNS: + the typecode of the attribute's type. If this is a scalar type, the + typecode sufficiently describes the scalar type and no further calls + need to be made. Valid scalar types include: OCI_TYPECODE_SIGNED8, + OCI_TYPECODE_UNSIGNED8, OCI_TYPECODE_SIGNED16, OCI_TYPECODE_UNSIGNED16, + OCI_TYPECODE_SIGNED32, OCI_TYPECODE_UNSIGNED32, OCI_TYPECODE_REAL, + OCI_TYPECODE_DOUBLE, OCI_TYPECODE_DATE, + OCI_TYPECODE_MLSLABEL, OROTCOID, OCI_TYPECODE_OCTET, or OROTCLOB. + This function converts the CREF (stored in the attribute) into a + typecode. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeElemType ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeElemType( OCIEnv *env, OCIError *err, const OCITypeElem *elem, + OCIType **elem_tdo ); +/* + PARAMETERS + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + elem_tdo (OUT) - If the function completes successfully, 'elem_tdo' + points to the type descriptor (in the object cache) of the type of + the element. + + REQUIRES + 1) All type accessors require that the type be pinned before calling + any accessor. This can be done by calling 'OCITypeByName()'. + 2) if 'elem' is not null, it must point to a valid type element descriptor + in the object cache. + + DESCRIPTION + Get the type tdo of the type of this element. + RETURNS + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + + NOTES + The type must be unpinned when the accessed information is no + longer needed. This can be done by calling 'OCIObjectUnpin()'. + */ + +/*------------------------- OCITypeElemFlags -------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeElemFlags( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemFlags - OCI Get a Elem's FLags + (inline, constant, virtual, constructor, + destructor). + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the flags of a type element (attribute, parameter). + RETURNS: + The flags of the type element. + NOTES: + The flag bits are not externally documented. Use only the macros + in the last section (ie. OCI_TYPEPARAM_IS_REQUIRED, and + OCI_TYPEELEM_IS_REF) to test for them only. The type must be unpinned + when the accessed information is no longer needed. + */ + +/*------------------------ OCITypeElemNumPrec ------------------------------*/ + +/* ** OBSOLETE ** */ +ub1 OCITypeElemNumPrec( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemNumPrec - Get a Number's Precision. This includes float, + decimal, real, double, and oracle number. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the precision of a float, decimal, long, unsigned long, real, + double, or Oracle number type. + RETURNS: + the precision of the float, decimal, long, unsigned long, real, double, + or Oracle number + */ + +/*------------------------- OCITypeElemNumScale -----------------------------*/ + +/* ** OBSOLETE ** */ +sb1 OCITypeElemNumScale( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemNumScale - Get a decimal or oracle Number's Scale + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the scale of a decimal, or Oracle number type. + RETURNS: + the scale of the decimal, or Oracle number + */ + +/*------------------------ OCITypeElemLength -------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeElemLength( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemLength - Get a raw, fixed or variable length String's + length in bytes. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the length of a raw, fixed or variable length string type. + RETURNS: + length of the raw, fixed or variable length string + */ + +/*----------------------- OCITypeElemCharSetID -----------------------------*/ + +/* ** OBSOLETE ** */ +ub2 OCITypeElemCharSetID( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemCharSetID - Get a fixed or variable length String's + character set ID + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the character set ID of a fixed or variable length string type. + RETURNS: + character set ID of the fixed or variable length string + */ + +/*---------------------- OCITypeElemCharSetForm ----------------------------*/ + +/* ** OBSOLETE ** */ +ub2 OCITypeElemCharSetForm( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemCharSetForm - Get a fixed or variable length String's + character set specification form. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the attribute information in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the character form of a fixed or variable length string type. + The character form is an enumerated value that can be one of the + 4 values below: + SQLCS_IMPLICIT for CHAR, VARCHAR2, CLOB w/o a specified set + SQLCS_NCHAR for NCHAR, NCHAR VARYING, NCLOB + SQLCS_EXPLICIT for CHAR, etc, with "CHARACTER SET ..." syntax + SQLCS_FLEXIBLE for PL/SQL "flexible" parameters + RETURNS: + character form of the fixed or variable string + */ + +/*--------------------- OCITypeElemParameterizedType ------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeElemParameterizedType( OCIEnv *env, OCIError *err, + const OCITypeElem *elem, + OCIType **type_stored ); +/* + NAME: OCITypeElemParameterizedType + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + type_stored (OUT) - If the function completes successfully, + and the parameterized type is complex, 'type_stored' is NULL. + Otherwise, 'type_stored' points to the type descriptor (in the + object cache) of the type that is stored in the parameterized + type. The caller must allocate space for the OCIType* + before calling this routine and must not write into the space. + REQUIRES: + All input parameters must be valid. + DESCRIPTION: + Get a descriptor to the parameter type of a parameterized type. + Parameterized types are types of the form: + REF T + VARRAY (n) OF T + etc, where T is the parameter in the parameterized type. + Additionally is_ref is set if the parameter is a PTR or REF. + For example, it is set for REF T or VARRAY(n) OF REF T. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) 'type_stored' is not NULL but points to NULL data. + NOTES: + Complex parameterized types will be in a future release (once + typedefs are supported. When setting the parameterized type + information, the user must typedef the contents if it's a + complex parameterized type. Ex. for varray>, use + 'typedef varray varcar' and then use varray. + */ + +/*----------------------- OCITypeElemExtTypeCode ----------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeElemExtTypeCode( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemExtTypeCode - OCI Get an element's SQLT constant. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the internal Oracle typecode associated with an attribute's type. + This is the actual typecode for the attribute when it gets mapped + to a column in the Oracle database. + RETURNS: + The Oracle typecode associated with the attribute's type. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*--------------------------------------------------------------------------*/ +/* ATTRIBUTE ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeAttrByName -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeAttrByName( OCIEnv *env, OCIError *err, const OCIType *tdo, + const oratext *name, ub4 n_length, + OCITypeElem **elem ); +/* + NAME: OCITypeAttrByName - OCI Get an Attribute By Name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + name (IN) - the attribute's name + n_length (IN) - length (in bytes) of the 'name' parameter + elem (OUT) - If this function completes successfully, 'elem' points to + the selected type element descriptor pertaining to the + attributein the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Get an attribute given its name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) the type does not contain an attribute with the input 'name'. + 3) 'name' is NULL. + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. + */ + +/*------------------------ OCITypeAttrNext ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeAttrNext( OCIEnv *env, OCIError *err, + OCITypeIter *iterator_ort, OCITypeElem **elem ); + +/* + NAME: OCITypeAttrNext - OCI Get an Attribute By Iteration. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + iterator_ort (IN/OUT) - iterator for retrieving the next attribute; + see OCITypeIterNew() to initialize iterator. + elem (OUT) - If this function completes successfully, 'elem' points to + the selected type element descriptor pertaining to the + attributein the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Iterate to the next attribute to retrieve. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_NO_DATA if there are no more attributes to iterate on; use + OCITypeIterSet() to reset the iterator if necessary. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*--------------------------------------------------------------------------*/ +/* COLLECTION ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeCollElem ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeCollElem( OCIEnv *env, OCIError *err, const OCIType *tdo, + OCITypeElem **element ); +/* + NAME: OCITypeCollElem + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the type descriptor in the object cache + element (IN/OUT) - If the function completes successfully, this + points to the descriptor for the collection's element. + It is stored in the same format as an ADT attribute's + descriptor. + If *element is NULL, OCITypeCollElem() implicitly allocates a + new instance of OCITypeElem in the object cache. This instance + will be + automatically freed at the end of the session, and does not have + to be freed explicitly. + If *element is not NULL, OCITypeCollElem() assumes that it + points to a valid OCITypeElem descriptor and will copy the + results into it. + REQUIRES: + All input parameters must be valid. + DESCRIPTION: + Get a pointer to the descriptor (OCITypeElem) of the element of an + array or the rowtype of a nested table. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) the type TDO does not point to a valid collection's type. + NOTES: + Complex parameterized types will be in a future release (once + typedefs are supported. When setting the parameterized type + information, the user must typedef the contents if it's a + complex parameterized type. Ex. for varray>, use + 'typedef varray varcar' and then use varray. + */ + +/*------------------------ OCITypeCollSize ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeCollSize( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *num_elems ); +/* + NAME: OCITypeCollSize - OCI Get a Collection's Number of Elements. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the type descriptor in the object cache + num_elems (OUT) - number of elements in collection + REQUIRES: + All input parameters must be valid. tdo points to an array type + defined as a domain. + DESCRIPTION: + Get the number of elements stored in a fixed array or the maximum + number of elements in a variable array. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) 'tdo' does not point to a domain with a collection type. + NOTES: + Complex parameterized types will be in a future release (once + typedefs are supported. When setting the parameterized type + information, the user must typedef the contents if it's a + complex parameterized type. Ex. for varray>, use + 'typedef varray varcar' and then use varray. + */ + +/*------------------------ OCITypeCollExtTypeCode ---------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeCollExtTypeCode( OCIEnv *env, OCIError *err, + const OCIType *tdo, OCITypeCode *sqt_code ); +/* + NAME: ortcsqt - OCI Get a Collection element's DTY constant. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the type descriptor in the object cache + sqt_code (OUT) - SQLT code of type element. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the SQLT constant associated with an domain's element type. + The SQLT codes are defined in and are needed for OCI/OOCI + use. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) 'tdo' does not point to a domain with a collection type. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* METHOD ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------- OCITypeMethodOverload --------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeMethodOverload( OCIEnv *env, OCIError *err, const OCIType *tdo, + const oratext *method_name, ub4 m_length ); +/* + NAME: OCITypeMethodOverload - OCI Get type's Number of Overloaded names + for the given method name. + PARAMETERS: + gp (IN/OUT) - pga environment handle. Any errors are recorded here. + tdo (IN) - pointer to to the type descriptor in the object cache + method_name (IN) - the method's name + m_length (IN) - length (in bytes) of the 'method_name' parameter + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Overloading of methods implies that more than one method may have the + same method name. This routine returns the number of methods that + have the given method name. If there are no methods with the input + method name, 'num_methods' is 0. The caller uses this information when + allocating space for the array of mdo and/or position pointers before + calling 'OCITypeMethodByName()' or 'ortgmps()'. + RETURNS: + The number of methods with the given name. 0 if none contains the + name. + NOTES: + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. + */ + +/*------------------------ OCITypeMethodByName ------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodByName( OCIEnv *env, OCIError *err, const OCIType *tdo, + const oratext *method_name, ub4 m_length, + OCITypeMethod **mdos ); +/* + NAME: OCITypeMethodByName - OCI Get one or more Methods with Name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + method_name (IN) - the methods' name + m_length (IN) - length (in bytes) of the 'name' parameter + mdos (OUT) - If this function completes successfully, 'mdos' points to + the selected methods in the object cache. The caller must + allocate space for the array of OCITypeMethod pointers before + calling this routine and must not write into the space. + The number of OCITypeMethod pointers that will be returned can + be obtained by calling 'OCITypeMethodOverload()'. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Get one or more methods given the name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) No methods in type has name 'name'. + 3) 'mdos' is not NULL but points to NULL data. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. + */ + +/*------------------------ OCITypeMethodNext --------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodNext( OCIEnv *env, OCIError *err, + OCITypeIter *iterator_ort, + OCITypeMethod **mdo ); + +/* + NAME: OCITypeMethodNext - OCI Get a Method By Iteration. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + iterator_ort (IN/OUT) - iterator for retrieving the next method; + see OCITypeIterNew() to set iterator. + mdo (OUT) - If this function completes successfully, 'mdo' points to + the selected method descriptor in the object cache. Positions + start at 1. The caller must allocate space for the + OCITypeMethod* before calling this routine and must not write + nto the space. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Iterate to the next method to retrieve. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_NO_DATA if there are no more attributes to iterate on; use + OCITypeIterSet() to reset the iterator if necessary. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) 'mdo' is not NULL but points to NULL data. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodName --------------------------------*/ + +/* ** OBSOLETE ** */ +oratext *OCITypeMethodName( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, ub4 *n_length ); +/* + NAME: OCITypeMethodName - OCI Get a Method's NaMe. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + n_length (OUT) - length (in bytes) of the 'name' parameter. The caller + must allocate space for the ub4 before calling this routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the (non-unique) real name of the method. + RETURNS: + the non-unique name of the method or NULL if there is an error. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodEncap -------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeEncap OCITypeMethodEncap( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo ); +/* + NAME: OCITypeMethodEncap - Get a Method's ENcapsulation (private/public). + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the encapsulation (private, or public) of a method. + RETURNS: + the encapsulation (private, or public) of the method + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodFlags -------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeMethodFlag OCITypeMethodFlags( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo ); +/* + NAME: OCITypeMethodFlags - OCI Get a Method's FLags + (inline, constant, virtual, constructor, + destructor). + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the flags (inline, constant, virutal, constructor, destructor) of + a method. + RETURNS: + the flags (inline, constant, virutal, constructor, destructor) of + the method + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodMap ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodMap( OCIEnv *env, OCIError *err, const OCIType *tdo, + OCITypeMethod **mdo ); +/* + NAME: OCITypeMethodMap - OCI Get the Method's MAP function. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + mdo (OUT) - If this function completes successfully, and there is a + map function for this type, 'mdo' points to the selected method + descriptor in the object cache. Otherwise, 'mdo' is null. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All required input parameters must not be NULL and must be valid. + DESCRIPTION: + A type may have only one map function. 'OCITypeMethodMap()' finds + this function, if it exists, and returns a reference and a pointer to + the method descriptor in the object cache. If the type does not have a + map (relative ordering) function, then 'mdo_ref' and 'mdo' are set + to null and an error is returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + the type does not contain a map function. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodOrder -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodOrder( OCIEnv *env, OCIError *err, const OCIType *tdo, + OCITypeMethod **mdo ); +/* + NAME: OCITypeMethodOrder - OCI Get the Method's ORder function. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + mdo (OUT) - If this function completes successfully, and there is a + map function for this type, 'mdo' points to the selected method + descriptor in the object cache. Otherwise, 'mdo' is null. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All required input parameters must not be NULL and must be valid. + DESCRIPTION: + A type may have only one ORder or MAP function. 'OCITypeMethodOrder()' + finds this function, if it exists, and returns a ref and a pointer + to the method descriptor in the object cache. If the type does not + have a map (relative ordering) function, then 'mdo_ref' and 'mdo' are + set to null and an error is returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + the type does not contain a map function. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodParams ------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeMethodParams( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo ); +/* + NAME: OCITypeMethodParams - OCI Get a Method's Number of Parameters. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the number of parameters in a method. + RETURNS: + the number of parameters in the method + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* RESULT ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*-------------------------- OCITypeResult ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeResult( OCIEnv *env, OCIError *err, const OCITypeMethod *mdo, + OCITypeElem **elem ); +/* + NAME: OCITypeResult - OCI Get a method's result type descriptor. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + elem (OUT) - If this function completes successfully, 'rdo' points to + the selected result (parameter) descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) 'elem' MUST be the address of an OCITypeElem pointer. + DESCRIPTION: + Get the result of a method. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) method returns no results. + NOTES: + The method must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* PARAMETER ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeParamByPos -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeParamByPos( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, ub4 position, + OCITypeElem **elem ); +/* + NAME: OCITypeParamByPos - OCI Get a Parameter in a method By Position. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + position (IN) - the parameter's position. Positions start at 1. + elem (OUT) - If this function completes successfully, 'elem' points to + the selected parameter descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + DESCRIPTION: + Get a parameter given its position in the method. Positions start + at 1. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) 'position' is not >= 1 and <= the number of parameters in the + method. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeParamByName -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeParamByName( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, + const oratext *name, ub4 n_length, + OCITypeElem **elem ); +/* + NAME: OCITypeParamByName - OCI Get a Parameter in a method By Name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + name (IN) - the parameter's name + n_length (IN) - length (in bytes) of the 'name' parameter + elem (OUT) - If this function completes successfully, 'elem' points to + the selected parameter descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'mdo' is not null, it must point to a valid method descriptor + in the object cache. + DESCRIPTION: + Get a parameter given its name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) the method does not contain a parameter with the input 'name'. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeParamPos ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeParamPos( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, + const oratext *name, ub4 n_length, ub4 *position, + OCITypeElem **elem ); +/* + NAME: OCITypeParamPos - OCI Get a parameter's position in a method + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + name (IN) - the parameter's name + n_length (IN) - length (in bytes) of the 'name' parameter + position (OUT) - If this function completes successfully, 'position' + points to the position of the parameter in the method starting + at position 1. position MUST point to space for a ub4. + elem (OUT) - If this function completes successfully, and + the input 'elem' is not NULL, 'elem' points to the selected + parameter descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'mdo' is not null, it must point to a valid method descriptor + in the object cache. + DESCRIPTION: + Get the position of a parameter in a method. Positions start at 1. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) the method does not contain a parameter with the input 'name'. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeParamElemMode -----------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeParamMode OCITypeElemParamMode( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemParamMode - OCI Get a parameter's mode + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the parameter descriptor in the object cache + (represented by an OCITypeElem) + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the mode (in, out, or in/out) of the parameter. + RETURNS: + the mode (in, out, or in/out) of the parameter + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------- OCITypeElemDefaultValue -------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeElemDefaultValue( OCIEnv *env, OCIError *err, + const OCITypeElem *elem, + ub4 *d_v_length ); +/* + NAME: OCITypeElemDefaultValue - OCI Get the element's Default Value. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the parameter descriptor in the object cache + (represented by an OCITypeElem) + d_v_length (OUT) - length (in bytes) of the returned default value. + The caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the default value in text form (PL/SQL) of an element. For V8.0, + this only makes sense for a method parameter. + RETURNS: + The default value (text) of the parameter. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* TYPE VERSION TABLE */ +/*--------------------------------------------------------------------------*/ + +/* For V8.0, the type version table is meant to be an internal data structure + only for Oracle clients for type version maintanence purposes. A more + general version of the API may be made public in subsequent releases. */ + + +/*--------------------------- OCITypeVTInit --------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeVTInit( OCIEnv *env, OCIError *err ); +/* + NAME: OCITypeVTInit - OCI type Version table INItialize + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + REQUIRES: + none + DESCRIPTION: + Allocate space for and initialize the type version table and the type + version table's index. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if internal errors occurrs during initialization. + */ + +/*--------------------------- OCITypeVTInsert -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeVTInsert( OCIEnv *env, OCIError *err, + const oratext *schema_name, ub4 s_n_length, + const oratext *type_name, ub4 t_n_length, + const oratext *user_version, ub4 u_v_length ); +/* + NAME: OCITypeVTInsert - OCI type Version table INSert entry. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + schema_name (IN, optional) - name of schema associated with the + type. By default, the user's schema name is used. + s_n_length (IN) - length of the 'schema_name' parameter + type_name (IN) - type name to insert + t_n_length (IN) - length (in bytes) of the 'type_name' parameter + user_version (IN) - user readable version of the type + u_v_length (IN) - length (in bytes) of the 'user_version' parameter + REQUIRES: + none + DESCRIPTION: + Insert an entry into the type version table and the type version + table's index. The entry's type name and user readable version + fields are updated with the input values. All other fields are + initialized to null. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is invalid. + 2) an entry for 'type_name' has already been registered in the + type version table. + */ + +/*------------------------------ OCITypeVTSelect ----------------------------*/ + +/* OCITypeVTSelect - OCI type VERSion table SELECT entry */ +/* ** OBSOLETE ** */ +sword OCITypeVTSelect( OCIEnv *env, OCIError *err, + const oratext *schema_name, ub4 s_n_length, + const oratext *type_name, ub4 t_n_length, + oratext **user_version, ub4 *u_v_length, + ub2 *version ); +/* + NAME: OCITypeVTSelect - OCI type Version table SELect entry. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + schema_name (IN, optional) - name of schema associated with the + type. By default, the user's schema name is used. + s_n_length (IN) - length of the 'schema_name' parameter + type_name (IN) - type name to select + t_n_length (IN) - length (in bytes) of the 'type_name' parameter + user_version (OUT, optional) - pointer to user readable version of the + type + u_v_length (OUT, optional) - length (in bytes) of the 'user_version' + parameter + version (OUT, optional) - internal type version + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Select an entry in the type version table by name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is invalid. + 2) an entry with 'type_name' does not exist. + */ + +/* Compatibility function - following function prototype retained for + compatibility only */ +sword ortgcty( OCIEnv *env, OCIError *err, OCIType *coll_tdo, + OCIType **collelem_tdo ); + +/*---------------------------------------------------------------------------*/ +/* Transient Type Construction functions */ +/*---------------------------------------------------------------------------*/ + +sword OCITypeBeginCreate(OCISvcCtx *svchp, OCIError *errhp, OCITypeCode tc, + OCIDuration dur, OCIType **type); +/* + NAME: OCITypeBeginCreate - OCI Type Begin Creation of a transient type. + REMARKS + Begins the construction process for a transient type. The type will be + anonymous (no name). To create a persistent named type, the CREATE TYPE + statement should be used from SQL. Transient types have no identity. + They are pure values. + PARAMETERS: + svchp (IN) - The OCI Service Context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + tc - The TypeCode for the type. The Typecode could + correspond to a User Defined Type or a Built-in type. + Currently, the permissible values for User Defined + Types are OCI_TYPECODE_OBJECT for an Object Type + (structured), OCI_TYPECODE_VARRAY for a VARRAY + collection type or OCI_TYPECODE_TABLE for a nested + table collection type. For Object types, + OCITypeAddAttr() needs to be called to add each of + the attribute types. For Collection types, + OCITypeSetCollection() needs to be called. + Subsequently, OCITypeEndCreate() needs to be called + to finish the creation process. + The permissible values for Built-in type codes are + specified in the user manual. Additional information + on built-ins if any (like precision, scale for + numbers, character set info for VARCHAR2s etc.) must + be set with a subsequent call to OCITypeSetBuiltin(). + Subsequently OCITypeEndCreate() needs to be called + to finish the creation process. + dur - The allocation duration for the Type. Could be a + predefined or a user defined duration. + type(OUT) - The OCIType (Type Descriptor) that is being + constructed. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + + +sword OCITypeSetCollection(OCISvcCtx *svchp, OCIError *errhp, OCIType *type, + OCIParam *collelem_info, ub4 coll_count); +/* + NAME: OCITypeSetCollection - OCI Type Set Collection information + REMARKS : + Set Collection type information. This call can be called only if the + OCIType has been constructed with a collection typecode. + PARAMETERS: + svchp (IN) - The OCI Service Context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type(IN OUT) - The OCIType (Type Descriptor) that is being + constructed. + collelem_info - collelem_info provides information on the collection + element. It is obtained by allocating an OCIParam + (parameter handle) and setting type information in + the OCIParam using OCIAttrSet() calls. + coll_count - The count of elements in the collection. Pass 0 for + a nested table (unbounded). + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +sword OCITypeSetBuiltin(OCISvcCtx *svchp, OCIError *errhp, OCIType *type, + OCIParam *builtin_info); +/* + NAME: OCITypeSetBuiltin - OCI Type Set Builtin information. + REMARKS: + Set Built-in type information. This call can be called only if the + OCIType has been constructed with a built-in typecode + (OCI_TYPECODE_NUMBER etc.). + PARAMETERS: + svchp (IN) - The OCI Service Context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type(IN OUT) - The OCIType (Type Descriptor) that is being + constructed. + builtin_info - builtin_info provides information on the built-in + (like precision, scale, charater set etc.). It is + obtained by allocating an OCIParam (parameter handle) + and setting type information in the OCIParam using + OCIAttrSet() calls. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +sword OCITypeAddAttr(OCISvcCtx *svchp, OCIError *errhp, OCIType *type, + const oratext *a_name, ub4 a_length, + OCIParam *attr_info); +/* + NAME: OCITypeAddAttr - OCI Type Add Attribute to an Object Type. + REMARKS: + Adds an attribute to an Object type (that was constructed earlier with + typecode OCI_TYPECODE_OBJECT). + PARAMETERS: + svchp (IN) - The OCI Service Context + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type (IN/OUT) - The Type description that is being constructed. + a_name(IN) - Optional. gives the name of the attribute. + a_length - Optional. gives length of attribute name. + attr_info - Information on the attribute. It is obtained by + allocating an OCIParam (parameter handle) and setting + type information in the OCIParam using OCIAttrSet() + calls. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +sword OCITypeEndCreate(OCISvcCtx *svchp, OCIError *errhp, OCIType *type); +/* + NAME: OCITypeEndCreate - OCI Type End Creation + REMARKS: + Finishes construction of a type description.Subsequently, only access + will be allowed. + PARAMETERS: + svchp (IN) - The OCI Service Context + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type (IN/OUT) - The Type description that is being constructed. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +/*=========================*/ +/* PUBLIC MACROS AND FLAGS */ +/*=========================*/ + +/*--------------------------------------------------------------------------*/ +/* TYPE ELEMENT FLAGS */ +/*--------------------------------------------------------------------------*/ + +#define OCI_TYPEELEM_REF 0x8000 /* element is a REF */ +#define OCI_TYPEPARAM_REQUIRED 0x0800 /* parameter is required */ + +/* macros to test flags */ +#define OCI_TYPEELEM_IS_REF(elem_flag) \ + (((elem_flag) & OCI_TYPEELEM_REF)!=0) +#define OCI_TYPEPARAM_IS_REQUIRED(param_flag) \ + (((param_flag) & OCI_TYPEPARAM_REQUIRED)!=0) + + +#endif /* ORT_ORACLE */ + diff --git a/OCI/include/xa.h b/OCI/include/xa.h new file mode 100644 index 0000000..9dcd519 --- /dev/null +++ b/OCI/include/xa.h @@ -0,0 +1,200 @@ +/* Copyright (c) 1992, 2006, Oracle. All rights reserved. */ + +/* + NAME + xa.h - + DESCRIPTION + + PUBLIC FUNCTION(S) + + PRIVATE FUNCTION(S) + + RETURNS + + NOTES + + + This is the public XA .h file + + MODIFIED (MM/DD/YY) + yohu 08/27/06 - XA/RAC project changes: XAER_AFFINITY + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + whe 09/01/99 - 976457:check __cplusplus for C++ code + ntang 10/20/98 - Remove TMCACHE & TMFORCL + abhide 08/04/97 - implement xaoforcl + abhide 07/23/97 - XA OTS project changes + schandra 02/20/96 - lint + abhide 04/07/94 - merge changes from branch 1.1.710.1 + abhide 02/14/94 - Creation + abhide 02/10/94 - Creation + abhide 02/10/94 - Creation +*/ +/* + * xa.h header + * Typed in from X/Open doc of March 13, 1990 + * Updated to Parsippany II draft, March, 1991 + * Updated to Co Review draft, 19 Sep 1991 + */ + +#ifndef XA_H +#define XA_H + + +/* + * Transaction branch identification: XID and NULLXID: + */ + + +#define XIDDATASIZE 128 /* size in bytes */ +#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */ +#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */ +struct xid_t { + long formatID; /* format identifier */ + long gtrid_length; /* value from 1 through 64 */ + long bqual_length; /* value from 1 through 64 */ + char data[XIDDATASIZE]; +}; +typedef struct xid_t XID; + +/* + * A value of -1 in formatID means that the XID is null. + */ +/* + * Declarations of routines by which RMs call TMs: + */ + +int ax_reg(int, XID *, long); +int ax_unreg(int, long); +/* + * XA Switch Data Structure + */ +#define RMNAMESZ 32 /* length of resource manager name, */ + /* including the null terminator */ +#define MAXINFOSIZE 256 /* maximum size in bytes of xa_info strings, */ + /* including the null terminator */ +struct xa_switch_t { + char name[RMNAMESZ]; /* name of resource manager */ + long flags; /* resource manager specific options */ + long version; /* must be 0 */ + + int (*xa_open_entry)(char *, int, long); /*xa_open function pointer*/ + int (*xa_close_entry)(char *, int, long); /*xa_close function pointer*/ + int (*xa_start_entry)(XID *, int, long); /*xa_start function pointer*/ + int (*xa_end_entry)(XID *, int, long); /*xa_end function pointer*/ + int (*xa_rollback_entry)(XID *, int, long); + /*xa_rollback function pointer*/ + int (*xa_prepare_entry)(XID *, int, long); /*xa_prepare function pointer*/ + int (*xa_commit_entry)(XID *, int, long); /*xa_commit function pointer*/ + int (*xa_recover_entry)(XID *, long, int, long); + /*xa_recover function pointer*/ + int (*xa_forget_entry)(XID *, int, long); /*xa_forget function pointer*/ + int (*xa_complete_entry)(int *, int *, int, long); +}; + +/* + * Flag definition for the RM switch + */ +#define TMNOFLAGS 0x00000000L /* no resource manager features + selected */ +#define TMREGISTER 0x00000001L /* resource manager dynamically + registers */ +#define TMNOMIGRATE 0x00000002L /* resource manager does not support + association migration */ +#define TMUSEASYNC 0x00000004L /* resource manager supports + asynchronous operations */ +/* + * Flag definitions for xa_ and ax_ routines + */ +/* Use TMNOFLAGS, defined above, when not specifying other flags */ +#define TMASYNC 0x80000000L /* perform routine asynchronously */ +#define TMONEPHASE 0x40000000L /* caller is using one-phase commit + optimisation */ +#define TMFAIL 0x20000000L /* dissociates caller and marks + transaction branch rollback-only */ +#define TMNOWAIT 0x10000000L /* return if blocking condition + exists */ +#define TMRESUME 0x08000000L /* caller is resuming association + with suspended transaction branch */ +#define TMSUCCESS 0x04000000L /* dissociate caller from transaction + branch */ +#define TMSUSPEND 0x02000000L /* caller is suspending, not ending, + association */ +#define TMSTARTRSCAN 0x01000000L /* start a recovery scan */ +#define TMENDRSCAN 0x00800000L /* end a recovery scan */ +#define TMMULTIPLE 0x00400000L /* wait for any asynchronous + operation */ +#define TMJOIN 0x00200000L /* caller is joining existing + transaction branch */ +#define TMMIGRATE 0x00100000L /* caller intends to perform + migration */ + +/* + * ax_() return codes (transaction manager reports to resource manager) + */ +#define TM_JOIN 2 /* caller is joining existing transaction + branch */ +#define TM_RESUME 1 /* caller is resuming association with + suspended transaction branch */ +#define TM_OK 0 /* normal execution */ +#define TMER_TMERR -1 /* an error occurred in the transaction + manager */ +#define TMER_INVAL -2 /* invalid arguments were given */ +#define TMER_PROTO -3 /* routine invoked in an improper context */ + +/* + * xa_() return codes (resource manager reports to transaction manager) + */ +#define XA_RBBASE 100 /* The inclusive lower bound of the + rollback codes */ +#define XA_RBROLLBACK XA_RBBASE /* The rollback was caused by an + unspecified reason */ +#define XA_RBCOMMFAIL XA_RBBASE+1 /* The rollback was caused by a + communication failure */ +#define XA_RBDEADLOCK XA_RBBASE+2 /* A deadlock was detected */ +#define XA_RBINTEGRITY XA_RBBASE+3 /* A condition that violates the + integrity of the resources was + detected */ +#define XA_RBOTHER XA_RBBASE+4 /* The resource manager rolled back the + transaction for a reason not on this + list */ +#define XA_RBPROTO XA_RBBASE+5 /* A protocal error occurred in the + resource manager */ +#define XA_RBTIMEOUT XA_RBBASE+6 /* A transaction branch took too long*/ +#define XA_RBTRANSIENT XA_RBBASE+7 /* May retry the transaction branch */ +#define XA_RBEND XA_RBTRANSIENT /* The inclusive upper bound of the + rollback codes */ + +#define XA_NOMIGRATE 9 /* resumption must occur where + suspension occurred */ +#define XA_HEURHAZ 8 /* the transaction branch may have been + heuristically completed */ +#define XA_HEURCOM 7 /* the transaction branch has been + heuristically comitted */ +#define XA_HEURRB 6 /* the transaction branch has been + heuristically rolled back */ +#define XA_HEURMIX 5 /* the transaction branch has been + heuristically committed and rolled + back */ +#define XA_RETRY 4 /* routine returned with no effect + and may be re-issued */ +#define XA_RDONLY 3 /* the transaction was read-only + and has been committed */ +#define XA_OK 0 /* normal execution */ +#define XAER_ASYNC -2 /* asynchronous operation already + outstanding */ +#define XAER_RMERR -3 /* a resource manager error occurred + in the transaction branch */ +#define XAER_NOTA -4 /* the XID is not valid */ +#define XAER_INVAL -5 /* invalid arguments were given */ +#define XAER_PROTO -6 /* routine invoked in an improper + context */ +#define XAER_RMFAIL -7 /* resource manager unavailable */ +#define XAER_DUPID -8 /* the XID already exists */ +#define XAER_OUTSIDE -9 /* resource manager doing work */ + /* outside global transaction */ + +#define XAER_AFFINITY -10 /* XA on RAC: resumption must occur on + RAC instance where the transaction + branch was created */ + +#endif /* ifndef XA_H */ diff --git a/OCI/lib/MSVC/vc8/oraocci11.sym b/OCI/lib/MSVC/vc8/oraocci11.sym new file mode 100644 index 0000000..237f3f3 Binary files /dev/null and b/OCI/lib/MSVC/vc8/oraocci11.sym differ diff --git a/OCI/lib/MSVC/vc8/oraocci11d.sym b/OCI/lib/MSVC/vc8/oraocci11d.sym new file mode 100644 index 0000000..e9af417 Binary files /dev/null and b/OCI/lib/MSVC/vc8/oraocci11d.sym differ diff --git a/OCI/lib/MSVC/vc9/oraocci11.sym b/OCI/lib/MSVC/vc9/oraocci11.sym new file mode 100644 index 0000000..7e61652 Binary files /dev/null and b/OCI/lib/MSVC/vc9/oraocci11.sym differ diff --git a/OCI/lib/MSVC/vc9/oraocci11d.sym b/OCI/lib/MSVC/vc9/oraocci11d.sym new file mode 100644 index 0000000..b2240bc Binary files /dev/null and b/OCI/lib/MSVC/vc9/oraocci11d.sym differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c060b9 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# ITK + +ITK模板 + +VisualStudio版本: 2015 + diff --git a/json-develop/.cirrus.yml b/json-develop/.cirrus.yml new file mode 100644 index 0000000..be63315 --- /dev/null +++ b/json-develop/.cirrus.yml @@ -0,0 +1,17 @@ +arm_container: + image: gcc:latest + +check_task: + check_script: + - wget https://github.com/Kitware/CMake/releases/download/v3.20.2/cmake-3.20.2.tar.gz + - tar xfz cmake-3.20.2.tar.gz + - cd cmake-3.20.2 + - ./configure + - make cmake ctest -j4 + - cd .. + - mkdir build + - cd build + - ../cmake-3.20.2/bin/cmake .. -DJSON_FastTests=ON + - make -j4 + - cd tests + - ../../cmake-3.20.2/bin/ctest -j4 diff --git a/json-develop/.clang-format b/json-develop/.clang-format new file mode 100644 index 0000000..5b9e3fd --- /dev/null +++ b/json-develop/.clang-format @@ -0,0 +1,84 @@ +#AccessModifierOffset: 2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +#AlignConsecutiveBitFields: false +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: false +AlignEscapedNewlines: Right +#AlignOperands: AlignAfterOperator +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +#AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +#BitFieldColonSpacing: Both +BreakBeforeBraces: Custom # or Allman +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + #BeforeLambdaBody: false + #BeforeWhile: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakStringLiterals: false +ColumnLimit: 0 +CompactNamespaces: false +ConstructorInitializerIndentWidth: 2 +Cpp11BracedListStyle: true +PointerAlignment: Left +FixNamespaceComments: true +IncludeBlocks: Preserve +#IndentCaseBlocks: false +IndentCaseLabels: true +IndentGotoLabels: false +IndentPPDirectives: BeforeHash +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ReflowComments: false +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++11 +TabWidth: 4 +UseTab: Never diff --git a/json-develop/.clang-tidy b/json-develop/.clang-tidy new file mode 100644 index 0000000..ff84c58 --- /dev/null +++ b/json-develop/.clang-tidy @@ -0,0 +1,59 @@ +Checks: '*, + -altera-id-dependent-backward-branch, + -altera-struct-pack-align, + -altera-unroll-loops, + -android-cloexec-fopen, + -bugprone-easily-swappable-parameters, + -cert-err58-cpp, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-avoid-do-while, + -cppcoreguidelines-avoid-goto, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-type-union-access, + -cppcoreguidelines-virtual-class-destructor, + -fuchsia-default-arguments-calls, + -fuchsia-default-arguments-declarations, + -fuchsia-overloaded-operator, + -google-explicit-constructor, + -google-readability-function-size, + -google-runtime-int, + -google-runtime-references, + -hicpp-avoid-goto, + -hicpp-explicit-conversions, + -hicpp-function-size, + -hicpp-no-array-decay, + -hicpp-no-assembler, + -hicpp-signed-bitwise, + -hicpp-uppercase-literal-suffix, + -llvm-header-guard, + -llvm-include-order, + -llvmlibc-*, + -misc-confusable-identifiers, + -misc-no-recursion, + -misc-non-private-member-variables-in-classes, + -modernize-concat-nested-namespaces, + -modernize-use-nodiscard, + -modernize-use-trailing-return-type, + -readability-function-cognitive-complexity, + -readability-function-size, + -readability-identifier-length, + -readability-magic-numbers, + -readability-redundant-access-specifiers, + -readability-simplify-boolean-expr, + -readability-uppercase-literal-suffix' + +CheckOptions: + - key: hicpp-special-member-functions.AllowSoleDefaultDtor + value: 1 + +WarningsAsErrors: '*' + +#HeaderFilterRegex: '.*nlohmann.*' +HeaderFilterRegex: '.*hpp$' diff --git a/json-develop/.github/CODEOWNERS b/json-develop/.github/CODEOWNERS new file mode 100644 index 0000000..4d5ee04 --- /dev/null +++ b/json-develop/.github/CODEOWNERS @@ -0,0 +1,6 @@ +# JSON for Modern C++ has been originally written by Niels Lohmann. +# Since 2013 over 140 contributors have helped to improve the library. +# This CODEOWNERS file is only to make sure that @nlohmann is requested +# for a code review in case of a pull request. + +* @nlohmann diff --git a/json-develop/.github/CODE_OF_CONDUCT.md b/json-develop/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..770b817 --- /dev/null +++ b/json-develop/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/json-develop/.github/CONTRIBUTING.md b/json-develop/.github/CONTRIBUTING.md new file mode 100644 index 0000000..4b6b4ae --- /dev/null +++ b/json-develop/.github/CONTRIBUTING.md @@ -0,0 +1,71 @@ +[![Issue Stats](http://issuestats.com/github/nlohmann/json/badge/pr?style=flat)](http://issuestats.com/github/nlohmann/json) [![Issue Stats](http://issuestats.com/github/nlohmann/json/badge/issue?style=flat)](http://issuestats.com/github/nlohmann/json) + +# How to contribute + +This project started as a little excuse to exercise some of the cool new C++11 features. Over time, people actually started to use the JSON library (yey!) and started to help improve it by proposing features, finding bugs, or even fixing my mistakes. I am really [thankful](https://github.com/nlohmann/json/blob/master/README.md#thanks) for this and try to keep track of all the helpers. + +To make it as easy as possible for you to contribute and for me to keep an overview, here are a few guidelines which should help us avoid all kinds of unnecessary work or disappointment. And of course, this document is subject to discussion, so please [create an issue](https://github.com/nlohmann/json/issues/new/choose) or a pull request if you find a way to improve it! + +## Private reports + +Usually, all issues are tracked publicly on [GitHub](https://github.com/nlohmann/json/issues). If you want to make a private report (e.g., for a vulnerability or to attach an example that is not meant to be published), please send an email to . + +## Prerequisites + +Please [create an issue](https://github.com/nlohmann/json/issues/new/choose), assuming one does not already exist, and describe your concern. Note you need a [GitHub account](https://github.com/signup/free) for this. + +## Describe your issue + +Clearly describe the issue: + +- If it is a bug, please describe how to **reproduce** it. If possible, attach a complete example which demonstrates the error. Please also state what you **expected** to happen instead of the error. +- If you propose a change or addition, try to give an **example** how the improved code could look like or how to use it. +- If you found a compilation error, please tell us which **compiler** (version and operating system) you used and paste the (relevant part of) the error messages to the ticket. + +Please stick to the provided issue template ([bug report](https://github.com/nlohmann/json/blob/develop/.github/ISSUE_TEMPLATE/bug.yml) if possible. For questions, feature or support requests, please [open a discussion](https://github.com/nlohmann/json/discussions/new). + +## Files to change + +:exclamation: Before you make any changes, note the single-header files [`single_include/nlohmann/json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) and [`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) are **generated** from the source files in the [`include/nlohmann` directory](https://github.com/nlohmann/json/tree/develop/include/nlohmann). Please **do not** edit the files `single_include/nlohmann/json.hpp` and `single_include/nlohmann/json_fwd.hpp` directly, but change the `include/nlohmann` sources and regenerate the files by executing `make amalgamate`. + +To make changes, you need to edit the following files: + +1. [`include/nlohmann/*`](https://github.com/nlohmann/json/tree/develop/include/nlohmann) - These files are the sources of the library. Before testing or creating a pull request, execute `make amalgamate` to regenerate `single_include/nlohmann/json.hpp` and `single_include/nlohmann/json_fwd.hpp`. + +2. [`tests/src/unit-*.cpp`](https://github.com/nlohmann/json/tree/develop/tests/src) - These files contain the [doctest](https://github.com/onqtam/doctest) unit tests which currently cover [100 %](https://coveralls.io/github/nlohmann/json) of the library's code. + + If you add or change a feature, please also add a unit test to this file. The unit tests can be compiled and executed with + + ```sh + $ mkdir build + $ cd build + $ cmake .. + $ cmake --build . + $ ctest + ``` + + The test cases are also executed with several different compilers on [Travis](https://travis-ci.org/nlohmann/json) once you open a pull request. + + +## Note + +- If you open a pull request, the code will be automatically tested with [Valgrind](http://valgrind.org)'s Memcheck tool to detect memory leaks. Please be aware that the execution with Valgrind _may_ in rare cases yield different behavior than running the code directly. This can result in failing unit tests which run successfully without Valgrind. +- There is a Makefile target `make pretty` which runs [Artistic Style](http://astyle.sourceforge.net) to fix indentation. If possible, run it before opening the pull request. Otherwise, we shall run it afterward. + +## Please don't + +- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means. +- Specifically, I am aware of compilation problems with **Microsoft Visual Studio** (there even is an [issue label](https://github.com/nlohmann/json/issues?utf8=✓&q=label%3A%22visual+studio%22+) for this kind of bug). I understand that even in 2016, complete C++11 support isn't there yet. But please also understand that I do not want to drop features or uglify the code just to make Microsoft's sub-standard compiler happy. The past has shown that there are ways to express the functionality such that the code compiles with the most recent MSVC - unfortunately, this is not the main objective of the project. +- Please refrain from proposing changes that would **break [JSON](https://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension. + - We shall not extend the library to **support comments**. There is quite some [controversy](https://www.reddit.com/r/programming/comments/4v6chu/why_json_doesnt_support_comments_douglas_crockford/) around this topic, and there were quite some [issues](https://github.com/nlohmann/json/issues/376) on this. We believe that JSON is fine without comments. + - We do not preserve the **insertion order of object elements**. The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". To this end, this library does not preserve insertion order of name/value pairs. (In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default.) Note this behavior conforms to the standard, and we shall not change it to any other order. If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map). + +- Please do not open pull requests that address **multiple issues**. + +## Wanted + +The following areas really need contribution: + +- Extending the **continuous integration** toward more exotic compilers such as Android NDK, Intel's Compiler, or the bleeding-edge versions Clang. +- Improving the efficiency of the **JSON parser**. The current parser is implemented as a naive recursive descent parser with hand coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the `json.hpp` header, and I am not aware of approaches similar to [`re2c`](http://re2c.org) for parsing. +- Extending and updating existing **benchmarks** to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting. diff --git a/json-develop/.github/FUNDING.yml b/json-develop/.github/FUNDING.yml new file mode 100644 index 0000000..a6c972e --- /dev/null +++ b/json-develop/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: nlohmann +custom: http://paypal.me/nlohmann diff --git a/json-develop/.github/ISSUE_TEMPLATE/bug.yaml b/json-develop/.github/ISSUE_TEMPLATE/bug.yaml new file mode 100644 index 0000000..571a1cc --- /dev/null +++ b/json-develop/.github/ISSUE_TEMPLATE/bug.yaml @@ -0,0 +1,93 @@ +name: Bug Report +description: Create a bug report +labels: + - 'kind: bug' +body: + - type: markdown + attributes: + value: > + Thanks for taking the time to fill out this bug report! + + Make sure you give it a short and specific **title** so that the report + is searchable and uniquely identifiable. + + Note that this form is for bug reports only. Please + [open a discussion](https://github.com/nlohmann/json/discussions/new) + for questions, feature requests, or support requests + - type: textarea + id: summary + attributes: + label: Description + description: > + Please provide an abstract description of the issue to the developers, + and why you consider it to be a bug. Please include any specific links + to the documentation, JSON specification, or code. + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Reproduction steps + description: > + How do you trigger the bug? Please walk us through step by step. Be as + specific as possible. + validations: + required: true + - type: textarea + id: results + attributes: + label: Expected vs. actual results + description: > + Please describe what you expected to happen after the steps above and + what actually happened. + validations: + required: true + - type: textarea + id: code + attributes: + label: Minimal code example + description: > + If possible, provide a small and self-contained example that triggers + the bug. Please understand that we cannot analyze and debug large code + bases. Please do not paste screenshots here. + render: Shell + - type: textarea + id: output + attributes: + label: Error messages + description: > + Please provide any kind of error output (compilation errors, exception + messages, stack traces, etc.) which can help to diagnose the error. + render: Shell + - type: input + id: compiler + attributes: + label: Compiler and operating system + description: > + On which operating systems and compilers have you observed the issue? + Include as many relevant details about the environment you experienced + the bug in. Make sure you use a + [supported compiler](https://github.com/nlohmann/json#supported-compilers). + validations: + required: true + - type: input + id: version + attributes: + label: Library version + description: > + Which version of the library did you use? If it is a released version, + please enter the version number (e.g., 3.11.2). Otherwise, please enter + the commit hash. If you got the library from another source as the + GitHub repository (e.g., via a package manager), please also state + this. + validations: + required: true + - type: checkboxes + id: validation + attributes: + label: Validation + description: > + Please check these additional steps: + options: + - label: The bug also occurs if the latest version from the [`develop`](https://github.com/nlohmann/json/tree/develop) branch is used. + - label: I can successfully [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests). diff --git a/json-develop/.github/ISSUE_TEMPLATE/config.yml b/json-develop/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..0e96633 --- /dev/null +++ b/json-develop/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Ask a question + url: https://github.com/nlohmann/json/discussions + about: Ask questions and discuss with other community members diff --git a/json-develop/.github/PULL_REQUEST_TEMPLATE.md b/json-develop/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..c9c7cb7 --- /dev/null +++ b/json-develop/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,19 @@ +[Describe your pull request here. Please read the text below the line, and make sure you follow the checklist.] + +* * * + +## Pull request checklist + +Read the [Contribution Guidelines](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md) for detailed information. + +- [ ] Changes are described in the pull request, or an [existing issue is referenced](https://github.com/nlohmann/json/issues). +- [ ] The test suite [compiles and runs](https://github.com/nlohmann/json/blob/develop/README.md#execute-unit-tests) without error. +- [ ] [Code coverage](https://coveralls.io/github/nlohmann/json) is 100%. Test cases can be added by editing the [test suite](https://github.com/nlohmann/json/tree/develop/test/src). +- [ ] The source code is amalgamated; that is, after making changes to the sources in the `include/nlohmann` directory, run `make amalgamate` to create the single-header files `single_include/nlohmann/json.hpp` and `single_include/nlohmann/json_fwd.hpp`. The whole process is described [here](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md#files-to-change). + +## Please don't + +- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means. +- Specifically, I am aware of compilation problems with **Microsoft Visual Studio** (there even is an [issue label](https://github.com/nlohmann/json/issues?utf8=✓&q=label%3A%22visual+studio%22+) for this kind of bug). I understand that even in 2016, complete C++11 support isn't there yet. But please also understand that I do not want to drop features or uglify the code just to make Microsoft's sub-standard compiler happy. The past has shown that there are ways to express the functionality such that the code compiles with the most recent MSVC - unfortunately, this is not the main objective of the project. +- Please refrain from proposing changes that would **break [JSON](https://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension. +- Please do not open pull requests that address **multiple issues**. diff --git a/json-develop/.github/SECURITY.md b/json-develop/.github/SECURITY.md new file mode 100644 index 0000000..4d010eb --- /dev/null +++ b/json-develop/.github/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Usually, all issues are tracked publicly on [GitHub](https://github.com/nlohmann/json/issues). If you want to make a private report (e.g., for a vulnerability or to attach an example that is not meant to be published), please send an email to . You can use [this key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69) for encryption. diff --git a/json-develop/.github/config.yml b/json-develop/.github/config.yml new file mode 100644 index 0000000..7a8f41e --- /dev/null +++ b/json-develop/.github/config.yml @@ -0,0 +1,19 @@ +# Configuration for sentiment-bot - https://github.com/behaviorbot/sentiment-bot + +# *Required* toxicity threshold between 0 and .99 with the higher numbers being the most toxic +# Anything higher than this threshold will be marked as toxic and commented on +sentimentBotToxicityThreshold: .7 + +# *Required* Comment to reply with +sentimentBotReplyComment: > + Please be sure to review the [code of conduct](https://github.com/nlohmann/json/blob/develop/CODE_OF_CONDUCT.md) and be respectful of other users. cc/ @nlohmann + + +# Configuration for request-info - https://github.com/behaviorbot/request-info + +# *Required* Comment to reply with +requestInfoReplyComment: > + We would appreciate it if you could provide us with more info about this issue or pull request! Please check the [issue template](https://github.com/nlohmann/json/blob/develop/.github/ISSUE_TEMPLATE.md) and the [pull request template](https://github.com/nlohmann/json/blob/develop/.github/PULL_REQUEST_TEMPLATE.md). + +# *OPTIONAL* Label to be added to Issues and Pull Requests with insufficient information given +requestInfoLabelToAdd: "state: needs more info" diff --git a/json-develop/.github/external_ci/appveyor.yml b/json-develop/.github/external_ci/appveyor.yml new file mode 100644 index 0000000..126ed99 --- /dev/null +++ b/json-develop/.github/external_ci/appveyor.yml @@ -0,0 +1,91 @@ +version: '{build}' + +# only build PRs and commits to develop branch +# (see https://help.appveyor.com/discussions/questions/55079-two-builds-per-commit-to-pull-request) +branches: + only: + - develop + +only_commits: + files: + - .github/external_ci/appveyor.yml + - cmake/ + - include/ + - tests/ + - CMakeLists.txt + +environment: + matrix: + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + configuration: Debug + platform: x86 + CXX_FLAGS: "/W4 /WX" + CMAKE_OPTIONS: "" + GENERATOR: Visual Studio 14 2015 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + configuration: Release + platform: x86 + CXX_FLAGS: "/W4 /WX" + CMAKE_OPTIONS: "" + GENERATOR: Visual Studio 14 2015 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + configuration: Release + platform: x86 + name: with_win_header + CXX_FLAGS: "/W4 /WX" + CMAKE_OPTIONS: "" + GENERATOR: Visual Studio 14 2015 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + configuration: Release + platform: x86 + CXX_FLAGS: "/permissive- /std:c++latest /utf-8 /W4 /WX" + CMAKE_OPTIONS: "" + GENERATOR: Visual Studio 15 2017 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + configuration: Release + platform: x86 + CXX_FLAGS: "/W4 /WX" + CMAKE_OPTIONS: "-DJSON_ImplicitConversions=OFF" + GENERATOR: Visual Studio 16 2019 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + configuration: Release + platform: x64 + CXX_FLAGS: "/W4 /WX" + CMAKE_OPTIONS: "" + GENERATOR: Visual Studio 14 2015 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + configuration: Release + platform: x64 + CXX_FLAGS: "/permissive- /std:c++latest /Zc:__cplusplus /utf-8 /W4 /WX" + CMAKE_OPTIONS: "" + GENERATOR: Visual Studio 15 2017 + +init: + - cmake --version + - msbuild /version + +install: + - if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32 + +before_build: + # for with_win_header build, inject the inclusion of Windows.h to the single-header library + - ps: if ($env:name -Eq "with_win_header") { $header_path = "single_include\nlohmann\json.hpp" } + - ps: if ($env:name -Eq "with_win_header") { "#include `n" + (Get-Content $header_path | Out-String) | Set-Content $header_path } + - cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On "%CMAKE_OPTIONS%" + +build_script: + - cmake --build . --config "%configuration%" --parallel 2 + +test_script: + - if "%configuration%"=="Release" ctest -C "%configuration%" --parallel 2 --output-on-failure + # On Debug builds, skip test-unicode_all + # as it is extremely slow to run and cause + # occasional timeouts on AppVeyor. + # More info: https://github.com/nlohmann/json/pull/1570 + - if "%configuration%"=="Debug" ctest --exclude-regex "test-unicode" -C "%configuration%" --parallel 2 --output-on-failure diff --git a/json-develop/.github/labeler.yml b/json-develop/.github/labeler.yml new file mode 100644 index 0000000..024d3e6 --- /dev/null +++ b/json-develop/.github/labeler.yml @@ -0,0 +1,38 @@ +version: 1 + +labels: +- label: "documentation" + files: + - "README.md" + +- label: "documentation" + files: + - "docs/.*" + +- label: "tests" + files: + - "tests/.*" + +- label: "CMake" + files: + - ".*CMakeLists.txt" + +- label: "CMake" + files: + - "cmake/.*" + +- label: "CI" + files: + - "github/workflows/.*" + +- label: "CI" + files: + - "github/external_ci/.*" + +- label: "S" + size-below: 10 +- label: "M" + size-above: 9 + size-below: 100 +- label: "L" + size-above: 100 diff --git a/json-develop/.github/stale.yml b/json-develop/.github/stale.yml new file mode 100644 index 0000000..d30c78b --- /dev/null +++ b/json-develop/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 30 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: "state: stale" +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/json-develop/.github/workflows/check_amalgamation.yml b/json-develop/.github/workflows/check_amalgamation.yml new file mode 100644 index 0000000..0fadb52 --- /dev/null +++ b/json-develop/.github/workflows/check_amalgamation.yml @@ -0,0 +1,70 @@ +name: "Check amalgamation" + +on: + pull_request: + +permissions: read-all + +jobs: + save: + runs-on: ubuntu-latest + steps: + - name: Save PR number + run: | + mkdir -p ./pr + echo ${{ github.event.number }} > ./pr/number + echo ${{ github.event.pull_request.user.login }} > ./pr/author + - uses: actions/upload-artifact@v2 + with: + name: pr + path: pr/ + + check: + runs-on: ubuntu-latest + env: + MAIN_DIR: ${{ github.workspace }}/main + INCLUDE_DIR: ${{ github.workspace }}/main/single_include/nlohmann + TOOL_DIR: ${{ github.workspace }}/tools/tools/amalgamate + ASTYLE_FLAGS: > + --style=allman --indent=spaces=4 --indent-modifiers --indent-switches --indent-preproc-block + --indent-preproc-define --indent-col1-comments --pad-oper --pad-header --align-pointer=type + --align-reference=type --add-brackets --convert-tabs --close-templates --lineend=linux --preserve-date + --formatted + + steps: + - name: Checkout pull request + uses: actions/checkout@v3 + with: + path: main + ref: ${{ github.event.pull_request.head.sha }} + + - name: Checkout tools + uses: actions/checkout@v3 + with: + path: tools + ref: develop + + - name: Install astyle + run: | + sudo apt-get update + sudo apt-get install astyle + + - name: Check amalgamation + run: | + cd $MAIN_DIR + + rm -fr $INCLUDE_DIR/json.hpp~ $INCLUDE_DIR/json_fwd.hpp~ + cp $INCLUDE_DIR/json.hpp $INCLUDE_DIR/json.hpp~ + cp $INCLUDE_DIR/json_fwd.hpp $INCLUDE_DIR/json_fwd.hpp~ + + python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s . + python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s . + echo "Format (1)" + astyle $ASTYLE_FLAGS --suffix=none --quiet $INCLUDE_DIR/json.hpp $INCLUDE_DIR/json_fwd.hpp + + diff $INCLUDE_DIR/json.hpp~ $INCLUDE_DIR/json.hpp + diff $INCLUDE_DIR/json_fwd.hpp~ $INCLUDE_DIR/json_fwd.hpp + + astyle $ASTYLE_FLAGS $(find docs/examples include tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name '*.cu' \) -not -path 'tests/thirdparty/*' -not -path 'tests/abi/include/nlohmann/*' | sort) + echo Check + find $MAIN_DIR -name '*.orig' -exec false {} \+ diff --git a/json-develop/.github/workflows/cifuzz.yml b/json-develop/.github/workflows/cifuzz.yml new file mode 100644 index 0000000..0fd355b --- /dev/null +++ b/json-develop/.github/workflows/cifuzz.yml @@ -0,0 +1,30 @@ +name: CIFuzz +on: [pull_request] + +permissions: + contents: read + +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'json' + dry-run: false + language: c++ + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'json' + fuzz-seconds: 300 + dry-run: false + language: c++ + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts diff --git a/json-develop/.github/workflows/codeql-analysis.yml b/json-develop/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..9a87e82 --- /dev/null +++ b/json-develop/.github/workflows/codeql-analysis.yml @@ -0,0 +1,42 @@ +name: "Code scanning - action" + +on: + push: + branches: + - develop + - master + - release/* + pull_request: + schedule: + - cron: '0 19 * * 1' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + CodeQL-Build: + + runs-on: ubuntu-latest + permissions: + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/json-develop/.github/workflows/comment_check_amalgamation.yml b/json-develop/.github/workflows/comment_check_amalgamation.yml new file mode 100644 index 0000000..2ab5ebb --- /dev/null +++ b/json-develop/.github/workflows/comment_check_amalgamation.yml @@ -0,0 +1,75 @@ +name: Comment Check Amalgamation +on: + workflow_run: + workflows: ["Check amalgamation"] + types: + - completed + +permissions: {} + +jobs: + comment: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + issues: read + pull-requests: write + steps: + - name: 'Download artifact' + uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 # v6.4.0 + with: + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{github.event.workflow_run.id }}, + }); + var matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "pr" + })[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data)); + - run: unzip pr.zip + + - name: 'Comment on PR' + uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 # v6.4.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var fs = require('fs'); + const author = fs.readFileSync('./author') + const issue_number = Number(fs.readFileSync('./number')); + const opts = github.rest.issues.listForRepo.endpoint.merge({ + owner: context.repo.owner, + repo: context.repo.repo, + creator: author, + state: 'all' + }) + let first = true + const issues = await github.paginate(opts) + for (const issue of issues) { + if (issue.number === issue_number) { + continue + } + if (issue.pull_request) { + first = false + break + } + } + await github.rest.issues.createComment({ + issue_number: issue_number, + owner: context.repo.owner, + repo: context.repo.repo, + body: '## 🔴 Amalgamation check failed! 🔴\nThe source code has not been amalgamated.' + + (first ? ' @' + author + ' Please read and follow the [Contribution Guidelines]' + + '(https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md#files-to-change).' + : '') + }) diff --git a/json-develop/.github/workflows/labeler.yml b/json-develop/.github/workflows/labeler.yml new file mode 100644 index 0000000..11925e1 --- /dev/null +++ b/json-develop/.github/workflows/labeler.yml @@ -0,0 +1,20 @@ +name: "Pull Request Labeler" + +on: + pull_request_target: + types: [opened, synchronize] + +permissions: {} + +jobs: + label: + permissions: + contents: read + pull-requests: write + + runs-on: ubuntu-latest + + steps: + - uses: srvaroa/labeler@master + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/json-develop/.github/workflows/macos.yml b/json-develop/.github/workflows/macos.yml new file mode 100644 index 0000000..b2cb429 --- /dev/null +++ b/json-develop/.github/workflows/macos.yml @@ -0,0 +1,67 @@ +name: macOS + +on: + push: + branches: + - develop + - master + - release/* + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + xcode_1: + runs-on: macos-11 + strategy: + matrix: + xcode: ['11.7', '12.4', '12.5.1', '13.0'] + env: + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DJSON_FastTests=ON + - name: Build + run: cmake --build build --parallel 10 + - name: Test + run: cd build ; ctest -j 10 --output-on-failure + + xcode_2: + runs-on: macos-12 + strategy: + matrix: + xcode: ['13.1', '13.2.1', '13.3.1', '13.4.1', '14.0', '14.0.1', '14.1'] + env: + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DJSON_FastTests=ON + - name: Build + run: cmake --build build --parallel 10 + - name: Test + run: cd build ; ctest -j 10 --output-on-failure + + xcode_standards: + runs-on: macos-latest + strategy: + matrix: + standard: [11, 14, 17, 20] + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DJSON_TestStandards=${{ matrix.standard }} + - name: Build + run: cmake --build build --parallel 10 + - name: Test + run: cd build ; ctest -j 10 --output-on-failure diff --git a/json-develop/.github/workflows/publish_documentation.yml b/json-develop/.github/workflows/publish_documentation.yml new file mode 100644 index 0000000..f5e5c2c --- /dev/null +++ b/json-develop/.github/workflows/publish_documentation.yml @@ -0,0 +1,35 @@ +name: Publish documentation + +# publish the documentation on every merge to develop branch +on: + push: + branches: + - develop + paths: + - docs/mkdocs/** + - docs/examples/** + workflow_dispatch: + +permissions: + contents: read + +# we don't want to have concurrent jobs, and we don't want to cancel running jobs to avoid broken publications +concurrency: + group: documentation + cancel-in-progress: false + +jobs: + publish_documentation: + if: github.repository == 'nlohmann/json' + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + + - name: Install and update PlantUML + run: sudo apt-get update ; sudo apt-get install -y plantuml + + - name: Install virtual environment + run: make install_venv -C docs/mkdocs + + - name: Publish documentation + run: make publish -C docs/mkdocs diff --git a/json-develop/.github/workflows/ubuntu.yml b/json-develop/.github/workflows/ubuntu.yml new file mode 100644 index 0000000..7a80c3e --- /dev/null +++ b/json-develop/.github/workflows/ubuntu.yml @@ -0,0 +1,232 @@ +name: Ubuntu + +on: + push: + branches: + - develop + - master + - release/* + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + ci_test_clang: + runs-on: ubuntu-latest + container: silkeh/clang:dev + steps: + - name: Install git and unzip + run: apt-get update ; apt-get install -y git unzip + - uses: actions/checkout@v3 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@latest + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_clang + + ci_test_gcc: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_gcc + + ci_static_analysis: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + strategy: + matrix: + target: [ci_cppcheck, ci_test_valgrind, ci_test_amalgamation, ci_test_single_header, ci_single_binaries, ci_infer] + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ${{ matrix.target }} + + ci_static_analysis_ubuntu: + runs-on: ubuntu-latest + strategy: + matrix: + target: [ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata] + steps: + - uses: actions/checkout@v3 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@latest + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ${{ matrix.target }} + + ci_static_analysis_clang: + runs-on: ubuntu-latest + container: silkeh/clang:dev + strategy: + matrix: + target: [ci_clang_tidy, ci_test_clang_sanitizer, ci_clang_analyze] + steps: + - name: Install git, clang-tools, and unzip + run: apt-get update ; apt-get install -y git clang-tools unzip + - uses: actions/checkout@v3 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@latest + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ${{ matrix.target }} + + ci_cmake_options: + runs-on: ubuntu-latest + container: ubuntu:focal + strategy: + matrix: + target: [ci_cmake_flags, ci_test_diagnostics, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls] + steps: + - name: Install build-essential + run: apt-get update ; apt-get install -y build-essential unzip wget git + - uses: actions/checkout@v3 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@latest + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ${{ matrix.target }} + + ci_test_coverage: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + permissions: + contents: read + checks: write + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_coverage + - name: Archive coverage report + uses: actions/upload-artifact@v3 + with: + name: code-coverage-report + path: ${{ github.workspace }}/build/html + - name: Publish report to Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ${{ github.workspace }}/build/json.info.filtered.noexcept + + ci_test_compilers_gcc: + runs-on: ubuntu-latest + strategy: + matrix: + compiler: ['4', '5', '6', '7', '8', '9', '10', '11', '12', 'latest'] + container: gcc:${{ matrix.compiler }} + steps: + - uses: actions/checkout@v3 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@latest + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_compiler_default + + ci_test_compilers_clang: + runs-on: ubuntu-latest + strategy: + matrix: + compiler: ['3.5', '3.6', '3.7', '3.8', '3.9', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15-bullseye', 'latest'] + container: silkeh/clang:${{ matrix.compiler }} + steps: + - name: Install unzip and git + run: apt-get update ; apt-get install -y unzip git + - uses: actions/checkout@v3 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@latest + - name: Set env FORCE_STDCPPFS_FLAG for clang 7 / 8 / 9 / 10 + run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV" + if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }} + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_compiler_default + + ci_test_compilers: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + strategy: + matrix: + compiler: [g++-4.8] + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_compiler_${{ matrix.compiler }} + + ci_test_standards: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + strategy: + matrix: + standard: [11, 14, 17, 20] + compiler: [gcc, clang] + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_test_${{ matrix.compiler }}_cxx${{ matrix.standard }} + + ci_cuda_example: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_cuda_example + + ci_icpc: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.2.0 + steps: + - uses: actions/checkout@v2 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: | + . /opt/intel/oneapi/setvars.sh + cmake --build build --target ci_icpc + + ci_reuse_compliance: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - name: Install REUSE tool + run: python -m pip install reuse + - name: Run REUSE lint + run: reuse lint + + ci_test_documentation: + runs-on: ubuntu-latest + strategy: + matrix: + target: [ci_test_examples, ci_test_api_documentation] + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ${{ matrix.target }} diff --git a/json-develop/.github/workflows/windows.yml b/json-develop/.github/workflows/windows.yml new file mode 100644 index 0000000..f4d4152 --- /dev/null +++ b/json-develop/.github/workflows/windows.yml @@ -0,0 +1,133 @@ +name: Windows + +on: + push: + branches: + - develop + - master + - release/* + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + mingw: + runs-on: windows-2019 + strategy: + matrix: + architecture: [x64, x86] + + steps: + - uses: actions/checkout@v3 + - name: Set up MinGW + uses: egor-tensin/setup-mingw@v2 + with: + platform: ${{ matrix.architecture }} + - name: Run CMake + run: cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + - name: Build + run: cmake --build build --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C Debug --output-on-failure + + msvc2019: + runs-on: windows-2019 + strategy: + matrix: + build_type: [Debug, Release] + architecture: [Win32, x64] + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX" + if: matrix.build_type == 'Release' + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_CXX_FLAGS="/W4 /WX" + if: matrix.build_type == 'Debug' + - name: Build + run: cmake --build build --config ${{ matrix.build_type }} --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure + + msvc2019_latest: + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 16 2019" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX" + - name: Build + run: cmake --build build --config Release --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C Release --output-on-failure + + msvc2022: + runs-on: windows-2022 + strategy: + matrix: + build_type: [Debug, Release] + architecture: [Win32, x64] + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX" + if: matrix.build_type == 'Release' + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_CXX_FLAGS="/W4 /WX" + if: matrix.build_type == 'Debug' + - name: Build + run: cmake --build build --config ${{ matrix.build_type }} --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure + + msvc2022_latest: + runs-on: windows-2022 + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX" + - name: Build + run: cmake --build build --config Release --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C Release --output-on-failure + + clang: + runs-on: windows-2019 + strategy: + matrix: + version: [11, 12, 13, 14, 15] + + steps: + - uses: actions/checkout@v3 + - name: Install Clang + run: curl -fsSL -o LLVM${{ matrix.version }}.exe https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.version }}.0.0/LLVM-${{ matrix.version }}.0.0-win64.exe ; 7z x LLVM${{ matrix.version }}.exe -y -o"C:/Program Files/LLVM" + - name: Run CMake + run: cmake -S . -B build -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang++.exe" -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + - name: Build + run: cmake --build build --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure + + clang-cl-11: + runs-on: windows-2019 + strategy: + matrix: + architecture: [Win32, x64] + + steps: + - uses: actions/checkout@v3 + - name: Run CMake + run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -T ClangCL -DJSON_BuildTests=On + - name: Build + run: cmake --build build --config Debug --parallel 10 + - name: Test + run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure diff --git a/json-develop/.gitignore b/json-develop/.gitignore new file mode 100644 index 0000000..30b62bf --- /dev/null +++ b/json-develop/.gitignore @@ -0,0 +1,41 @@ +*.dSYM +*.o +*.gcno +*.gcda +.DS_Store + +.wsjcpp-logs/* +.wsjcpp/* + +/.idea +/cmake-build-* + +# Visual Studio / Visual Studio Code +/.vs/ +/.vscode/ +/out/ + +# clangd cache +/.cache/ + +# build directories (vscode-cmake-tools, user-defined, ...) +/build*/ + +# fuzzers +/tests/corpus_* +/tests/parse_*_fuzzer + +# documentation +/docs/docset/docSet.dsidx +/docs/docset/JSON_for_Modern_C++.docset/ +/docs/docset/JSON_for_Modern_C++.tgz +/docs/mkdocs/docs/__pycache__/ +/docs/mkdocs/docs/examples/ +/docs/mkdocs/docs/images/json.gif +/docs/mkdocs/site/ +/docs/mkdocs/venv/ + +# serve_header +/localhost.pem +/localhost-key.pem +/serve_header.yml diff --git a/json-develop/.lgtm.yml b/json-develop/.lgtm.yml new file mode 100644 index 0000000..b62f9fb --- /dev/null +++ b/json-develop/.lgtm.yml @@ -0,0 +1,4 @@ +path_classifiers: + thirdparty: + - /tools/amalgamate + - /tools/cpplint diff --git a/json-develop/.reuse/README.md b/json-develop/.reuse/README.md new file mode 100644 index 0000000..29c2b67 --- /dev/null +++ b/json-develop/.reuse/README.md @@ -0,0 +1,7 @@ +# REUSE Software + +This directory contains supporting files to make the project compliant with the REUSE specification. + +The root `Makefile` contains a target `reuse` that updates copyright headers and checks for compliance. + +See for more information. diff --git a/json-develop/.reuse/dep5 b/json-develop/.reuse/dep5 new file mode 100644 index 0000000..315cae9 --- /dev/null +++ b/json-develop/.reuse/dep5 @@ -0,0 +1,32 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: json +Upstream-Contact: Niels Lohmann +Source: https://github.com/nlohmann/json + +Files: * +Copyright: 2013-2022 Niels Lohmann +License: MIT + +Files: tests/thirdparty/doctest/* +Copyright: 2016-2021 Viktor Kirilov +License: MIT + +Files: tests/thirdparty/fifo_map/* +Copyright: 2015-2017 Niels Lohmann +License: MIT + +Files: tests/thirdparty/Fuzzer/* +Copyright: 2003-2022, LLVM Project. +License: Apache-2.0 + +Files: tests/thirdparty/imapdl/* +Copyright: 2017 Georg Sauthoff +License: GPL-3.0-only + +Files: tools/amalgamate/* +Copyright: 2012 Erik Edlund +License: BSD-3-Clause + +Files: tools/gdb_pretty_printer +Copyright: 2020 Hannes Domani +License: MIT diff --git a/json-develop/.reuse/templates/json.jinja2 b/json-develop/.reuse/templates/json.jinja2 new file mode 100644 index 0000000..4abf481 --- /dev/null +++ b/json-develop/.reuse/templates/json.jinja2 @@ -0,0 +1,11 @@ + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ +| | |__ | | | | | | version 3.11.2 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +{% for copyright_line in copyright_lines %} +{{ copyright_line }} +{% endfor %} +{% for expression in spdx_expressions %} +SPDX-License-Identifier: {{ expression }} +{% endfor %} diff --git a/json-develop/.reuse/templates/json_support.jinja2 b/json-develop/.reuse/templates/json_support.jinja2 new file mode 100644 index 0000000..1fab99f --- /dev/null +++ b/json-develop/.reuse/templates/json_support.jinja2 @@ -0,0 +1,11 @@ + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ (supporting code) +| | |__ | | | | | | version 3.11.2 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +{% for copyright_line in copyright_lines %} +{{ copyright_line }} +{% endfor %} +{% for expression in spdx_expressions %} +SPDX-License-Identifier: {{ expression }} +{% endfor %} diff --git a/json-develop/BUILD.bazel b/json-develop/BUILD.bazel new file mode 100644 index 0000000..15d84f1 --- /dev/null +++ b/json-develop/BUILD.bazel @@ -0,0 +1,53 @@ +cc_library( + name = "json", + hdrs = [ + "include/nlohmann/adl_serializer.hpp", + "include/nlohmann/byte_container_with_subtype.hpp", + "include/nlohmann/detail/abi_macros.hpp", + "include/nlohmann/detail/conversions/from_json.hpp", + "include/nlohmann/detail/conversions/to_chars.hpp", + "include/nlohmann/detail/conversions/to_json.hpp", + "include/nlohmann/detail/exceptions.hpp", + "include/nlohmann/detail/hash.hpp", + "include/nlohmann/detail/input/binary_reader.hpp", + "include/nlohmann/detail/input/input_adapters.hpp", + "include/nlohmann/detail/input/json_sax.hpp", + "include/nlohmann/detail/input/lexer.hpp", + "include/nlohmann/detail/input/parser.hpp", + "include/nlohmann/detail/input/position_t.hpp", + "include/nlohmann/detail/iterators/internal_iterator.hpp", + "include/nlohmann/detail/iterators/iter_impl.hpp", + "include/nlohmann/detail/iterators/iteration_proxy.hpp", + "include/nlohmann/detail/iterators/iterator_traits.hpp", + "include/nlohmann/detail/iterators/json_reverse_iterator.hpp", + "include/nlohmann/detail/iterators/primitive_iterator.hpp", + "include/nlohmann/detail/json_custom_base_class.hpp", + "include/nlohmann/detail/json_pointer.hpp", + "include/nlohmann/detail/json_ref.hpp", + "include/nlohmann/detail/macro_scope.hpp", + "include/nlohmann/detail/macro_unscope.hpp", + "include/nlohmann/detail/meta/call_std/begin.hpp", + "include/nlohmann/detail/meta/call_std/end.hpp", + "include/nlohmann/detail/meta/cpp_future.hpp", + "include/nlohmann/detail/meta/detected.hpp", + "include/nlohmann/detail/meta/identity_tag.hpp", + "include/nlohmann/detail/meta/is_sax.hpp", + "include/nlohmann/detail/meta/std_fs.hpp", + "include/nlohmann/detail/meta/type_traits.hpp", + "include/nlohmann/detail/meta/void_t.hpp", + "include/nlohmann/detail/output/binary_writer.hpp", + "include/nlohmann/detail/output/output_adapters.hpp", + "include/nlohmann/detail/output/serializer.hpp", + "include/nlohmann/detail/string_concat.hpp", + "include/nlohmann/detail/string_escape.hpp", + "include/nlohmann/detail/value_t.hpp", + "include/nlohmann/json.hpp", + "include/nlohmann/json_fwd.hpp", + "include/nlohmann/ordered_map.hpp", + "include/nlohmann/thirdparty/hedley/hedley.hpp", + "include/nlohmann/thirdparty/hedley/hedley_undef.hpp", + ], + includes = ["include"], + visibility = ["//visibility:public"], + alwayslink = True, +) diff --git a/json-develop/CITATION.cff b/json-develop/CITATION.cff new file mode 100644 index 0000000..cc9d702 --- /dev/null +++ b/json-develop/CITATION.cff @@ -0,0 +1,14 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +authors: + - family-names: Lohmann + given-names: Niels + orcid: https://orcid.org/0000-0001-9037-795X + email: mail@nlohmann.me + website: https://nlohmann.me +title: "JSON for Modern C++" +version: 3.11.2 +date-released: 2022-08-12 +license: MIT +repository-code: "https://github.com/nlohmann" +url: https://json.nlohmann.me diff --git a/json-develop/CMakeLists.txt b/json-develop/CMakeLists.txt new file mode 100644 index 0000000..f942e04 --- /dev/null +++ b/json-develop/CMakeLists.txt @@ -0,0 +1,209 @@ +cmake_minimum_required(VERSION 3.1) + +## +## PROJECT +## name and version +## +project(nlohmann_json VERSION 3.11.2 LANGUAGES CXX) + +## +## MAIN_PROJECT CHECK +## determine if nlohmann_json is built as a subproject (using add_subdirectory) or if it is the main project +## +set(MAIN_PROJECT OFF) +if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(MAIN_PROJECT ON) +endif() + +## +## INCLUDE +## +## +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) +include(ExternalProject) + +## +## OPTIONS +## + +if (POLICY CMP0077) + # Allow CMake 3.13+ to override options when using FetchContent / add_subdirectory. + cmake_policy(SET CMP0077 NEW) +endif () + +# VERSION_GREATER_EQUAL is not available in CMake 3.1 +if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)) + set(JSON_BuildTests_INIT ON) +else() + set(JSON_BuildTests_INIT OFF) +endif() +option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ${JSON_BuildTests_INIT}) +option(JSON_CI "Enable CI build targets." OFF) +option(JSON_Diagnostics "Use extended diagnostic messages." OFF) +option(JSON_GlobalUDLs "Place use-defined string literals in the global namespace." ON) +option(JSON_ImplicitConversions "Enable implicit conversions." ON) +option(JSON_DisableEnumSerialization "Disable default integer enum serialization." OFF) +option(JSON_LegacyDiscardedValueComparison "Enable legacy discarded value comparison." OFF) +option(JSON_Install "Install CMake targets during install step." ${MAIN_PROJECT}) +option(JSON_MultipleHeaders "Use non-amalgamated version of the library." ON) +option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF) + +if (JSON_CI) + include(ci) +endif () + +## +## CONFIGURATION +## +include(GNUInstallDirs) + +set(NLOHMANN_JSON_TARGET_NAME ${PROJECT_NAME}) +set(NLOHMANN_JSON_CONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}" CACHE INTERNAL "") +set(NLOHMANN_JSON_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") +set(NLOHMANN_JSON_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") +set(NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE "cmake/config.cmake.in") +set(NLOHMANN_JSON_CMAKE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}") +set(NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE "${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}ConfigVersion.cmake") +set(NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE "${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Config.cmake") +set(NLOHMANN_JSON_CMAKE_PROJECT_TARGETS_FILE "${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Targets.cmake") +set(NLOHMANN_JSON_PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/pkgconfig") + +if (JSON_MultipleHeaders) + set(NLOHMANN_JSON_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/include/") + message(STATUS "Using the multi-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}") +else() + set(NLOHMANN_JSON_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/single_include/") + message(STATUS "Using the single-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}") +endif() + +if (NOT JSON_ImplicitConversions) + message(STATUS "Implicit conversions are disabled") +endif() + +if (JSON_DisableEnumSerialization) + message(STATUS "Enum integer serialization is disabled") +endif() + +if (JSON_LegacyDiscardedValueComparison) + message(STATUS "Legacy discarded value comparison enabled") +endif() + +if (JSON_Diagnostics) + message(STATUS "Diagnostics enabled") +endif() + +if (JSON_SystemInclude) + set(NLOHMANN_JSON_SYSTEM_INCLUDE "SYSTEM") +endif() + +## +## TARGET +## create target and add include path +## +add_library(${NLOHMANN_JSON_TARGET_NAME} INTERFACE) +add_library(${PROJECT_NAME}::${NLOHMANN_JSON_TARGET_NAME} ALIAS ${NLOHMANN_JSON_TARGET_NAME}) +if (${CMAKE_VERSION} VERSION_LESS "3.8.0") + target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_range_for) +else() + target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_std_11) +endif() + +target_compile_definitions( + ${NLOHMANN_JSON_TARGET_NAME} + INTERFACE + $<$>:JSON_USE_GLOBAL_UDLS=0> + $<$>:JSON_USE_IMPLICIT_CONVERSIONS=0> + $<$:JSON_DISABLE_ENUM_SERIALIZATION=1> + $<$:JSON_DIAGNOSTICS=1> + $<$:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1> +) + +target_include_directories( + ${NLOHMANN_JSON_TARGET_NAME} + ${NLOHMANN_JSON_SYSTEM_INCLUDE} INTERFACE + $ + $ +) + +## add debug view definition file for msvc (natvis) +if (MSVC) + set(NLOHMANN_ADD_NATVIS TRUE) + set(NLOHMANN_NATVIS_FILE "nlohmann_json.natvis") + target_sources( + ${NLOHMANN_JSON_TARGET_NAME} + INTERFACE + $ + $ + ) +endif() + +# Install a pkg-config file, so other tools can find this. +CONFIGURE_FILE( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" +) + +## +## TESTS +## create and configure the unit test target +## +if (JSON_BuildTests) + include(CTest) + enable_testing() + add_subdirectory(tests) +endif() + +## +## INSTALL +## install header files, generate and install cmake config files for find_package() +## +include(CMakePackageConfigHelpers) +# use a custom package version config file instead of +# write_basic_package_version_file to ensure that it's architecture-independent +# https://github.com/nlohmann/json/issues/1697 +configure_file( + "cmake/nlohmann_jsonConfigVersion.cmake.in" + ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE} + @ONLY +) +configure_file( + ${NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE} + ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE} + @ONLY +) + +if(JSON_Install) + install( + DIRECTORY ${NLOHMANN_JSON_INCLUDE_BUILD_DIR} + DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR} + ) + install( + FILES ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE} ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE} + DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR} + ) + if (NLOHMANN_ADD_NATVIS) + install( + FILES ${NLOHMANN_NATVIS_FILE} + DESTINATION . + ) + endif() + export( + TARGETS ${NLOHMANN_JSON_TARGET_NAME} + NAMESPACE ${PROJECT_NAME}:: + FILE ${NLOHMANN_JSON_CMAKE_PROJECT_TARGETS_FILE} + ) + install( + TARGETS ${NLOHMANN_JSON_TARGET_NAME} + EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME} + INCLUDES DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR} + ) + install( + EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME} + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR} + ) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION ${NLOHMANN_JSON_PKGCONFIG_INSTALL_DIR} + ) +endif() diff --git a/json-develop/ChangeLog.md b/json-develop/ChangeLog.md new file mode 100644 index 0000000..656d68b --- /dev/null +++ b/json-develop/ChangeLog.md @@ -0,0 +1,2943 @@ +# Changelog +All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [3.11.2](https://github.com/nlohmann/json/releases/tag/3.11.2) (2022-08-12) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.11.1...3.11.2) + +- MSVC natvis visualizer does not work after introduction of inline ABI namespace [\#3696](https://github.com/nlohmann/json/issues/3696) +- The use of parenthesis gives compilation errors in some situations [\#3682](https://github.com/nlohmann/json/issues/3682) +- extern from/to\_json result in linker error [\#3657](https://github.com/nlohmann/json/issues/3657) +- json\_fwd.hpp no longer standalone [\#3656](https://github.com/nlohmann/json/issues/3656) +- regression: `.value` is compilation error. [\#3655](https://github.com/nlohmann/json/issues/3655) +- Regression: no match for 'operator!=' comparing json\_pointer and const char \*/string\_t [\#3654](https://github.com/nlohmann/json/issues/3654) +- Regression: call to member function 'value' is ambiguous [\#3652](https://github.com/nlohmann/json/issues/3652) +- macOS 10.15 Actions runner image deprecation [\#3612](https://github.com/nlohmann/json/issues/3612) + +- generate\_natvis.py: validate version number; cleanup [\#3698](https://github.com/nlohmann/json/pull/3698) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add Python script for generating Natvis file and update file for 3.11.2 [\#3697](https://github.com/nlohmann/json/pull/3697) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- fix typo in json\_pointer.md [\#3692](https://github.com/nlohmann/json/pull/3692) ([eltociear](https://github.com/eltociear)) +- Add amalgamated json-fwd.hpp to release [\#3687](https://github.com/nlohmann/json/pull/3687) ([nlohmann](https://github.com/nlohmann)) +- Documentation updates for 3.11.2 [\#3686](https://github.com/nlohmann/json/pull/3686) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Make json\_pointer usable as map key \(again\) [\#3685](https://github.com/nlohmann/json/pull/3685) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Deprecate json\_pointer/string\_t comparisons [\#3684](https://github.com/nlohmann/json/pull/3684) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Restructure inline namespace and allow version component to be disabled [\#3683](https://github.com/nlohmann/json/pull/3683) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Properly constrain non-string json\_pointer overloads [\#3681](https://github.com/nlohmann/json/pull/3681) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Amalgamate the forward declaration header [\#3679](https://github.com/nlohmann/json/pull/3679) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix 'const' qualifier on bool& has no effect [\#3678](https://github.com/nlohmann/json/pull/3678) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix whitespace in workflow files [\#3675](https://github.com/nlohmann/json/pull/3675) ([nlohmann](https://github.com/nlohmann)) +- Attempt to fix labeler permissions [\#3674](https://github.com/nlohmann/json/pull/3674) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Refine 'Publish documentation' workflow [\#3673](https://github.com/nlohmann/json/pull/3673) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Documentation change [\#3672](https://github.com/nlohmann/json/pull/3672) ([nlohmann](https://github.com/nlohmann)) +- Add labeler action [\#3671](https://github.com/nlohmann/json/pull/3671) ([nlohmann](https://github.com/nlohmann)) +- Complete contributor list [\#3670](https://github.com/nlohmann/json/pull/3670) ([nlohmann](https://github.com/nlohmann)) +- Add json\_pointer/string\_t equality comparison operators [\#3664](https://github.com/nlohmann/json/pull/3664) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Reimplement value\(\) access functions [\#3663](https://github.com/nlohmann/json/pull/3663) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Complete contributor list [\#3662](https://github.com/nlohmann/json/pull/3662) ([nlohmann](https://github.com/nlohmann)) +- Adjust naming of GitHub action jobs [\#3661](https://github.com/nlohmann/json/pull/3661) ([nlohmann](https://github.com/nlohmann)) +- Publish documentation on push to develop branch [\#3660](https://github.com/nlohmann/json/pull/3660) ([nlohmann](https://github.com/nlohmann)) +- Add Discord badge to README [\#3651](https://github.com/nlohmann/json/pull/3651) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Miscellaneous small fixes [\#3643](https://github.com/nlohmann/json/pull/3643) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Minor BJData fixes [\#3637](https://github.com/nlohmann/json/pull/3637) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Update CI [\#3626](https://github.com/nlohmann/json/pull/3626) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) + +## [v3.11.1](https://github.com/nlohmann/json/releases/tag/v3.11.1) (2022-08-01) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.11.0...v3.11.1) + +- Regression: no matching literal operator for call to 'operator""\_json' [\#3645](https://github.com/nlohmann/json/issues/3645) +- \_json operator""\(\) [\#3644](https://github.com/nlohmann/json/issues/3644) + +- Fix global UDLs [\#3646](https://github.com/nlohmann/json/pull/3646) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) + +## [v3.11.0](https://github.com/nlohmann/json/releases/tag/v3.11.0) (2022-08-01) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.5...v3.11.0) + +- ICPC: warning \#1098: the qualifier on this friend declaration is ignored [\#3632](https://github.com/nlohmann/json/issues/3632) +- Starting with 3.10.4, just adding `\#include json.hpp` causes compile error: `overload resolution selected deleted operator '=' [\#3620](https://github.com/nlohmann/json/issues/3620) +- xwidgets doesn't compile with version \>3.10.3 [\#3602](https://github.com/nlohmann/json/issues/3602) +- json\_pointer\_\_pop\_back.cpp example does not compile [\#3600](https://github.com/nlohmann/json/issues/3600) +- nlohmann::json::array 'push\_back' is ambiguous [\#3589](https://github.com/nlohmann/json/issues/3589) +- Multiple versions causing conflict [\#3588](https://github.com/nlohmann/json/issues/3588) +- ERROR: ThreadSanitizer: SEGV on unknown address [\#3584](https://github.com/nlohmann/json/issues/3584) +- unicode4 test consistently fails on RISC-V hardware [\#3579](https://github.com/nlohmann/json/issues/3579) +- sax\_parse\(iterator, json\_sax\_t \*\) string callback clobbers spaces [\#3574](https://github.com/nlohmann/json/issues/3574) +- Nlohmann JSON Parse crash with raylib-cpp [\#3570](https://github.com/nlohmann/json/issues/3570) +- ordered\_json doesn't accept keys of types other than string\_t \(e.g., string\_view\) [\#3558](https://github.com/nlohmann/json/issues/3558) +- turning an object into an array [\#3547](https://github.com/nlohmann/json/issues/3547) +- json:parse\_bjdata\_fuzzer: ASSERT: ref\_stack.back\(\)-\>is\_array\(\) [\#3541](https://github.com/nlohmann/json/issues/3541) +- Warning about potential null dereference in GCC 12.1 \(Fedora 36\) [\#3525](https://github.com/nlohmann/json/issues/3525) +- Enable 32bit unit test in CI [\#3524](https://github.com/nlohmann/json/issues/3524) +- Error when roundtripping BJData [\#3519](https://github.com/nlohmann/json/issues/3519) +- ASSERT error while parsing BJData [\#3513](https://github.com/nlohmann/json/issues/3513) +- An exception occurred when sending a string with double quotes [\#3504](https://github.com/nlohmann/json/issues/3504) +- Binary reader for BJData creates incorrect SAX events [\#3503](https://github.com/nlohmann/json/issues/3503) +- It can't support "nan", "inf", "-inf" for float type [\#3494](https://github.com/nlohmann/json/issues/3494) +- ASAN error while parsing BJData \(Heap-buffer-overflow READ 1\) [\#3492](https://github.com/nlohmann/json/issues/3492) +- UBSAN error while parsing BJData \(Null-dereference\) [\#3491](https://github.com/nlohmann/json/issues/3491) +- UBSAN error while parsing BJData \(Invalid-bool-value\) [\#3490](https://github.com/nlohmann/json/issues/3490) +- json:parse\_bjdata\_fuzzer reaches assertion [\#3475](https://github.com/nlohmann/json/issues/3475) +- Compilation with -fmodules-ts and use inside of a module [\#3472](https://github.com/nlohmann/json/issues/3472) +- json.exception.parse\_error.101 only occurs outside of IDE [\#3467](https://github.com/nlohmann/json/issues/3467) +- json:parse\_bjdata\_fuzzer reaches assertion [\#3461](https://github.com/nlohmann/json/issues/3461) +- NLOHMANN\_DEFINE\_TYPE\_NON\_INTRUSIVE\_WITH\_DEFAULT can not parse { "key" : null} [\#3458](https://github.com/nlohmann/json/issues/3458) +- Unable to compile when using Microsoft's \_CRTDBG [\#3457](https://github.com/nlohmann/json/issues/3457) +- Compilation errors when including `` and using `--std=c++17` or above \(MinGW/Win10\) [\#3449](https://github.com/nlohmann/json/issues/3449) +- Weird things on for statement [\#3447](https://github.com/nlohmann/json/issues/3447) +- Parsing error when there is a json string within a Json [\#3445](https://github.com/nlohmann/json/issues/3445) +- ordered\_json vs json types comparison [\#3443](https://github.com/nlohmann/json/issues/3443) +- Error occurred when converting nlohmann::json to std::any [\#3428](https://github.com/nlohmann/json/issues/3428) +- I was forced to report an assertion error when copying an array of strings [\#3419](https://github.com/nlohmann/json/issues/3419) +- About Serialization Error invalid UTF-8 byte at index [\#3414](https://github.com/nlohmann/json/issues/3414) +- Comparison of NaN differs between json and float [\#3409](https://github.com/nlohmann/json/issues/3409) +- when i use it in C++ sserver,it it constantly show that fatal error: adl\_serializer.hpp: No such file or directory [\#3404](https://github.com/nlohmann/json/issues/3404) +- parse error [\#3403](https://github.com/nlohmann/json/issues/3403) +- CMake script MAIN\_PROJECT always OFF [\#3390](https://github.com/nlohmann/json/issues/3390) +- Parser unable to handle large floating point numbers [\#3389](https://github.com/nlohmann/json/issues/3389) +- Compilation error if json\_pointer is used with alternative string type [\#3388](https://github.com/nlohmann/json/issues/3388) +- Unit tests conversions & items fail to build \(Clang \<4.0/C++14 only\) [\#3384](https://github.com/nlohmann/json/issues/3384) +- Regression test for \#3070 is not being run and fails when enabled [\#3377](https://github.com/nlohmann/json/issues/3377) +- Refactor unit tests to use more convenient doctest assertion macros [\#3365](https://github.com/nlohmann/json/issues/3365) +- An json.h issue reported in a static code analyzer [\#3361](https://github.com/nlohmann/json/issues/3361) +- Mixing different JSON\_DIAGNOSTICS settings in separately compiled units leads to core [\#3360](https://github.com/nlohmann/json/issues/3360) +- json::out\_of\_range exception matches against lot of others while testing [\#3352](https://github.com/nlohmann/json/issues/3352) +- use mipsel-openwrt-linux-g++ -std=c++11 to compile, it has some errors "error: 'snprintf' is not a member of 'std'" [\#3349](https://github.com/nlohmann/json/issues/3349) +- Add proper issue templates [\#3348](https://github.com/nlohmann/json/issues/3348) +- switch from json to ordered\_json [\#3343](https://github.com/nlohmann/json/issues/3343) +- Json dump use to compilation errors [\#3339](https://github.com/nlohmann/json/issues/3339) +- Ambiguous conversion from nlohmann::basic\_json\<\> to custom class. [\#3333](https://github.com/nlohmann/json/issues/3333) +- Iterator doesn't satisfy std::incrementable because post-increment may change constness [\#3331](https://github.com/nlohmann/json/issues/3331) +- Inconsistent handling of floating point numbers after parse\(\) [\#3329](https://github.com/nlohmann/json/issues/3329) +- Documentation for `ordered_json` should show proper use of the `parse()` function. [\#3325](https://github.com/nlohmann/json/issues/3325) +- "type must be boolean, but is object" error thrown on non-boolean object [\#3319](https://github.com/nlohmann/json/issues/3319) +- Incomplete Type in request parms [\#3318](https://github.com/nlohmann/json/issues/3318) +- 小米 MIX4 MIUI13 bug [\#3316](https://github.com/nlohmann/json/issues/3316) +- json.exception.parse\_error.101 when parsing data received over a socket [\#3313](https://github.com/nlohmann/json/issues/3313) +- Parse to custom class from unordered\_json breaks on G++11.2.0 with C++20 [\#3312](https://github.com/nlohmann/json/issues/3312) +- try to assign dumped string to a class member varible [\#3300](https://github.com/nlohmann/json/issues/3300) +- includedir in pkgconfig is error if install\_headers\(\) has subdir argument. [\#3284](https://github.com/nlohmann/json/issues/3284) +- SHA-256 sum of json-3.10.5.tar.xz changes over time \(but not the content itself\) [\#3281](https://github.com/nlohmann/json/issues/3281) +- items\(\) method does not follow order of json message [\#3278](https://github.com/nlohmann/json/issues/3278) +- Perplexing template deduction failure serialising a 3rd party type using base class [\#3267](https://github.com/nlohmann/json/issues/3267) +- json.hpp 'isfinite' is not a member of 'std' also isinf; snprintf; stoull and to\_string members of std [\#3263](https://github.com/nlohmann/json/issues/3263) +- JSON build fails for C++ cmake [\#3256](https://github.com/nlohmann/json/issues/3256) +- Unexpected implicit conversion [\#3254](https://github.com/nlohmann/json/issues/3254) +- Add a function that checks for valid json in a C++ string [\#3245](https://github.com/nlohmann/json/issues/3245) +- Replace use of standard IO from error handling [\#3239](https://github.com/nlohmann/json/issues/3239) +- Use Catch for unit tests [\#3232](https://github.com/nlohmann/json/issues/3232) +- Exception thrown during initialization causes a memory leak [\#3215](https://github.com/nlohmann/json/issues/3215) +- Tests failing when compiling with c++20 [\#3207](https://github.com/nlohmann/json/issues/3207) +- ambiguous regression [\#3204](https://github.com/nlohmann/json/issues/3204) +- Deserialization: if class is\_constructible from std::string wrong from\_json overload is being selected, compilation failed [\#3171](https://github.com/nlohmann/json/issues/3171) +- 'clang++ ./json.hpp' with no usage: Compiler syntax problem in clang 3.7.0 \(tizen :/ \) [\#3153](https://github.com/nlohmann/json/issues/3153) +- build failure on upcoming gcc-12: test/src/unit-regression1.cpp:392:22: error: ambiguous overload for 'operator=' [\#3138](https://github.com/nlohmann/json/issues/3138) +- Applying JSON patch creates parent object [\#3134](https://github.com/nlohmann/json/issues/3134) +- Iterators cannot be used with range-v3 [\#3130](https://github.com/nlohmann/json/issues/3130) +- std::shared\_ptr\ == nlohmann::json compiles, which seem undesirable [\#3026](https://github.com/nlohmann/json/issues/3026) +- Error in test\download\_test\_data.vcxproj custom build step when compiling with Visual Studio 2019 16.7.7 msbuild on Windows 10 [\#2593](https://github.com/nlohmann/json/issues/2593) +- Consider putting the user-defined literals in a namespace [\#1682](https://github.com/nlohmann/json/issues/1682) +- Using versioned namespaces [\#1539](https://github.com/nlohmann/json/issues/1539) +- How can I use std::string\_view as the json\_key to "operator \[\]" ? [\#1529](https://github.com/nlohmann/json/issues/1529) +- serialize std::variant\<...\> [\#1261](https://github.com/nlohmann/json/issues/1261) + +- Prepare 3.11.0 release [\#3635](https://github.com/nlohmann/json/pull/3635) ([nlohmann](https://github.com/nlohmann)) +- Fix warning [\#3634](https://github.com/nlohmann/json/pull/3634) ([nlohmann](https://github.com/nlohmann)) +- Add license header to new files [\#3633](https://github.com/nlohmann/json/pull/3633) ([nlohmann](https://github.com/nlohmann)) +- Add a unit test including windows.h [\#3631](https://github.com/nlohmann/json/pull/3631) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fixed latest build error in msvc platform [\#3630](https://github.com/nlohmann/json/pull/3630) ([KsaNL](https://github.com/KsaNL)) +- Add regression tests for \#3204 and \#3333 [\#3629](https://github.com/nlohmann/json/pull/3629) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix patch::add creating nonexistent parents [\#3628](https://github.com/nlohmann/json/pull/3628) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Adjust JSON Pointer examples [\#3622](https://github.com/nlohmann/json/pull/3622) ([nlohmann](https://github.com/nlohmann)) +- Disable exceptions on ICPC [\#3621](https://github.com/nlohmann/json/pull/3621) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- build: install .pc and .cmake files to share/ [\#3619](https://github.com/nlohmann/json/pull/3619) ([Tachi107](https://github.com/Tachi107)) +- Fix MinGW CI failures [\#3618](https://github.com/nlohmann/json/pull/3618) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix Unicode test timeout \(for real this time!\) [\#3614](https://github.com/nlohmann/json/pull/3614) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Use 'concurrency' in GitHub workflows [\#3610](https://github.com/nlohmann/json/pull/3610) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Use swap\(\) by ADL [\#3609](https://github.com/nlohmann/json/pull/3609) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Move UDLs out of the global namespace [\#3605](https://github.com/nlohmann/json/pull/3605) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Re-add value\_type detection to distinguish string types [\#3604](https://github.com/nlohmann/json/pull/3604) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add operator\<\<\(json\_pointer\) [\#3601](https://github.com/nlohmann/json/pull/3601) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add documentation for comparing json and ordered\_json [\#3599](https://github.com/nlohmann/json/pull/3599) ([nlohmann](https://github.com/nlohmann)) +- Clean up after \#3581 [\#3596](https://github.com/nlohmann/json/pull/3596) ([nlohmann](https://github.com/nlohmann)) +- Add assertion if nullptr is passed to parse function [\#3593](https://github.com/nlohmann/json/pull/3593) ([nlohmann](https://github.com/nlohmann)) +- Minor documentation fixes [\#3592](https://github.com/nlohmann/json/pull/3592) ([nlohmann](https://github.com/nlohmann)) +- Add versioned, ABI-tagged inline namespace and namespace macros [\#3590](https://github.com/nlohmann/json/pull/3590) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add badge for https://repology.org/project/nlohmann-json/versions [\#3586](https://github.com/nlohmann/json/pull/3586) ([nlohmann](https://github.com/nlohmann)) +- Add error message if test suite cannot be found [\#3585](https://github.com/nlohmann/json/pull/3585) ([nlohmann](https://github.com/nlohmann)) +- add patch\_inplace function [\#3581](https://github.com/nlohmann/json/pull/3581) ([wolfv](https://github.com/wolfv)) +- Enable overriding test properties and set Unicode test timeouts [\#3580](https://github.com/nlohmann/json/pull/3580) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Ignore output directory [\#3572](https://github.com/nlohmann/json/pull/3572) ([NN---](https://github.com/NN---)) +- Optimize output vector adapter write [\#3569](https://github.com/nlohmann/json/pull/3569) ([romainreignier](https://github.com/romainreignier)) +- Add overloads for more key types to ordered\_map and fix ordered\_map::erase\(first, last\) with first == last [\#3564](https://github.com/nlohmann/json/pull/3564) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Make certain usage patterns more prominent in the README [\#3557](https://github.com/nlohmann/json/pull/3557) ([jez](https://github.com/jez)) +- CI: fix "JSON\_MultipleHeaders" option spelling [\#3555](https://github.com/nlohmann/json/pull/3555) ([karzhenkov](https://github.com/karzhenkov)) +- More documentation updates for 3.11.0 [\#3553](https://github.com/nlohmann/json/pull/3553) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Use DOCTEST\_\* compiler macros and suppress pragmas warning [\#3550](https://github.com/nlohmann/json/pull/3550) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add unit test to make sure iterator\_input\_adapter advances iterators correctly [\#3548](https://github.com/nlohmann/json/pull/3548) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Use REUSE framework [\#3546](https://github.com/nlohmann/json/pull/3546) ([nlohmann](https://github.com/nlohmann)) +- Use `std::iterator_traits` to extract `iterator_category` [\#3544](https://github.com/nlohmann/json/pull/3544) ([Mike-Leo-Smith](https://github.com/Mike-Leo-Smith)) +- BJData dimension length can not be string\_t::npos, fix \#3541 [\#3543](https://github.com/nlohmann/json/pull/3543) ([fangq](https://github.com/fangq)) +- Allow disabling default enum conversions [\#3536](https://github.com/nlohmann/json/pull/3536) ([zxey](https://github.com/zxey)) +- Add to\_json\(\) for std::vector\::reference [\#3534](https://github.com/nlohmann/json/pull/3534) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- CI: Enable 32bit unit test \(3\) [\#3532](https://github.com/nlohmann/json/pull/3532) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Use new CI image [\#3528](https://github.com/nlohmann/json/pull/3528) ([nlohmann](https://github.com/nlohmann)) +- Fix ndarray dimension signedness, fix ndarray length overflow \(2\); add 32bit unit test [\#3523](https://github.com/nlohmann/json/pull/3523) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Small documentation fixes [\#3520](https://github.com/nlohmann/json/pull/3520) ([nlohmann](https://github.com/nlohmann)) +- Add assertion to converting constructor [\#3517](https://github.com/nlohmann/json/pull/3517) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- CI: Remove -Wstrict-overflow [\#3516](https://github.com/nlohmann/json/pull/3516) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix nlohmann/json\#3513, explain is\_ndarray flag [\#3514](https://github.com/nlohmann/json/pull/3514) ([fangq](https://github.com/fangq)) +- Prevent ndarray size vector from recursive use, fix nlohmann/json\#3503 [\#3505](https://github.com/nlohmann/json/pull/3505) ([fangq](https://github.com/fangq)) +- prevent ndarray dimension vector from recusive array, nlohmann/json\#3500 [\#3502](https://github.com/nlohmann/json/pull/3502) ([fangq](https://github.com/fangq)) +- Discard optimized containers with negative counts in UBJSON/BJData \(\#3491,\#3492,\#3490\) [\#3500](https://github.com/nlohmann/json/pull/3500) ([fangq](https://github.com/fangq)) +- Update json.hpp [\#3499](https://github.com/nlohmann/json/pull/3499) ([ivanovmp](https://github.com/ivanovmp)) +- Add assertion for invariant in SAX-DOM parser [\#3498](https://github.com/nlohmann/json/pull/3498) ([nlohmann](https://github.com/nlohmann)) +- Add more macOS builders [\#3485](https://github.com/nlohmann/json/pull/3485) ([nlohmann](https://github.com/nlohmann)) +- change bjdata ndarray flag to detect negative size, as part of \#3475 [\#3479](https://github.com/nlohmann/json/pull/3479) ([fangq](https://github.com/fangq)) +- Document fuzzer usage [\#3478](https://github.com/nlohmann/json/pull/3478) ([nlohmann](https://github.com/nlohmann)) +- Add build step for ICPC \(with fixes\) [\#3465](https://github.com/nlohmann/json/pull/3465) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Complete documentation for 3.11.0 [\#3464](https://github.com/nlohmann/json/pull/3464) ([nlohmann](https://github.com/nlohmann)) +- Handle invalid BJData optimized type, fix \#3461 [\#3463](https://github.com/nlohmann/json/pull/3463) ([fangq](https://github.com/fangq)) +- Reorganize directories [\#3462](https://github.com/nlohmann/json/pull/3462) ([nlohmann](https://github.com/nlohmann)) +- Enable rapid testing and development on Compiler Explorer [\#3456](https://github.com/nlohmann/json/pull/3456) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- cpplint 1.6.0 [\#3454](https://github.com/nlohmann/json/pull/3454) ([nlohmann](https://github.com/nlohmann)) +- Disable regression test for \#3070 on GCC \<8.4 [\#3451](https://github.com/nlohmann/json/pull/3451) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix C++20/gcc-12 issues \(Part 2\) [\#3446](https://github.com/nlohmann/json/pull/3446) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Overwork documentation [\#3444](https://github.com/nlohmann/json/pull/3444) ([nlohmann](https://github.com/nlohmann)) +- Fix typo in basic\_json documentation [\#3439](https://github.com/nlohmann/json/pull/3439) ([jhnlee](https://github.com/jhnlee)) +- Exclude std::any from implicit conversion \(fixes \#3428\) [\#3437](https://github.com/nlohmann/json/pull/3437) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Document which version introduced the macros [\#3431](https://github.com/nlohmann/json/pull/3431) ([nlohmann](https://github.com/nlohmann)) +- Fix constraints on from\_json\(\) for strings \(fixes \#3171, \#3267, \#3312, \#3384\) [\#3427](https://github.com/nlohmann/json/pull/3427) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- at.md: fix typo [\#3426](https://github.com/nlohmann/json/pull/3426) ([heinemml](https://github.com/heinemml)) +- Implement support for string\_view \(attempt no. 3\) [\#3423](https://github.com/nlohmann/json/pull/3423) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- CI: speedup AppVeyor builds by ~30% [\#3422](https://github.com/nlohmann/json/pull/3422) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Restore disabled check for \#3070 \(except on MSVC\) [\#3421](https://github.com/nlohmann/json/pull/3421) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Update CI image [\#3420](https://github.com/nlohmann/json/pull/3420) ([nlohmann](https://github.com/nlohmann)) +- Add check if different version is also included [\#3418](https://github.com/nlohmann/json/pull/3418) ([nlohmann](https://github.com/nlohmann)) +- Report the right \_\_cplusplus value for MSVC in basic\_json meta\(\) [\#3417](https://github.com/nlohmann/json/pull/3417) ([flagarde](https://github.com/flagarde)) +- CI: windows-2016 has been deprecated; remove jobs [\#3416](https://github.com/nlohmann/json/pull/3416) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Re-template json\_pointer on string type [\#3415](https://github.com/nlohmann/json/pull/3415) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Refactor unit tests to use more convenient doctest assertion macros \(Part 2\) [\#3405](https://github.com/nlohmann/json/pull/3405) ([kkarbowiak](https://github.com/kkarbowiak)) +- Refactor unit tests to use more convenient doctest assertion macros [\#3393](https://github.com/nlohmann/json/pull/3393) ([kkarbowiak](https://github.com/kkarbowiak)) +- Improve unit testing \(Part 1\) [\#3380](https://github.com/nlohmann/json/pull/3380) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix C++20/gcc-12 issues \(Part 1\) [\#3379](https://github.com/nlohmann/json/pull/3379) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add clarification to avoid misunderstanding that cause \#3360 [\#3378](https://github.com/nlohmann/json/pull/3378) ([puffetto](https://github.com/puffetto)) +- Fix ordered\_map ctor with initializer\_list \(fixes \#3343\) [\#3370](https://github.com/nlohmann/json/pull/3370) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Fix and update CI [\#3368](https://github.com/nlohmann/json/pull/3368) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- FetchContent\_MakeAvailable [\#3351](https://github.com/nlohmann/json/pull/3351) ([nlohmann](https://github.com/nlohmann)) +- Avoid clash with Arduino defines [\#3338](https://github.com/nlohmann/json/pull/3338) ([DarkZeros](https://github.com/DarkZeros)) +- Support UBJSON-derived Binary JData \(BJData\) format [\#3336](https://github.com/nlohmann/json/pull/3336) ([fangq](https://github.com/fangq)) +- Make iterator operator++/--\(int\) equality-preserving [\#3332](https://github.com/nlohmann/json/pull/3332) ([falbrechtskirchinger](https://github.com/falbrechtskirchinger)) +- Add note on parsing ordered\_json [\#3326](https://github.com/nlohmann/json/pull/3326) ([nlohmann](https://github.com/nlohmann)) +- Fix CITATION.cff and add automatic validation of your citation metadata [\#3320](https://github.com/nlohmann/json/pull/3320) ([fdiblen](https://github.com/fdiblen)) +- .github/workflows/windows.yml: Add support for Visual Studio 2022 [\#3295](https://github.com/nlohmann/json/pull/3295) ([t-b](https://github.com/t-b)) +- Add maintainer targets to create source archive [\#3289](https://github.com/nlohmann/json/pull/3289) ([nlohmann](https://github.com/nlohmann)) +- Fix a typo [\#3265](https://github.com/nlohmann/json/pull/3265) ([fhuberts](https://github.com/fhuberts)) +- Fix typo [\#3249](https://github.com/nlohmann/json/pull/3249) ([rex4539](https://github.com/rex4539)) +- Add documentation for JSON Lines [\#3247](https://github.com/nlohmann/json/pull/3247) ([nlohmann](https://github.com/nlohmann)) +- Improve documentation InputType and IteratorType [\#3246](https://github.com/nlohmann/json/pull/3246) ([nlohmann](https://github.com/nlohmann)) +- Remove stringstream [\#3244](https://github.com/nlohmann/json/pull/3244) ([nlohmann](https://github.com/nlohmann)) +- fix \_MSC\_VER version to check for std::filesystem [\#3240](https://github.com/nlohmann/json/pull/3240) ([gcerretani](https://github.com/gcerretani)) +- Add macros NLOHMANN\_DEFINE\_TYPE\_INTRUSIVE\_WITH\_DEFAULT and ...\_NON\_INTRUSIVE\_WITH\_DEFAULT [\#3143](https://github.com/nlohmann/json/pull/3143) ([pketelsen](https://github.com/pketelsen)) + +## [v3.10.5](https://github.com/nlohmann/json/releases/tag/v3.10.5) (2022-01-03) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.4...v3.10.5) + +- \#include \ doesn't work with gcc-7 when `-std=c++17` is specified. [\#3203](https://github.com/nlohmann/json/issues/3203) +- Not able to use nlohmann json with c++ code built using emscripten to wasm [\#3200](https://github.com/nlohmann/json/issues/3200) +- Warning for shadowed variables [\#3188](https://github.com/nlohmann/json/issues/3188) +- Accessing missing keys on const json object leads to assert [\#3183](https://github.com/nlohmann/json/issues/3183) +- Data member is available, but null is reported, and program throws error [\#3173](https://github.com/nlohmann/json/issues/3173) +- serialization problem, from\_json need construct new object [\#3169](https://github.com/nlohmann/json/issues/3169) +- std::filesystem unavailable on macOS lower deployment targets [\#3156](https://github.com/nlohmann/json/issues/3156) +- \[json.exception.type\_error.305\] cannot use operator\[\] with a string argument with string [\#3151](https://github.com/nlohmann/json/issues/3151) +- json::dump\(\) is not compatible with C++ standards [\#3147](https://github.com/nlohmann/json/issues/3147) +- Issue with json::parse decoding codepoints [\#3142](https://github.com/nlohmann/json/issues/3142) +- Simple parse of json object thinks it should be an array [\#3136](https://github.com/nlohmann/json/issues/3136) +- How to properly read a Json string that may be null in some cases? [\#3135](https://github.com/nlohmann/json/issues/3135) +- Deadlock on create json - windows only [\#3129](https://github.com/nlohmann/json/issues/3129) +- Wrong parsing of int64 values nearest of limit [\#3126](https://github.com/nlohmann/json/issues/3126) +- ordered\_json doesn't support range based erase [\#3108](https://github.com/nlohmann/json/issues/3108) +- Apple build failed with json/single\_include/nlohmann/json.hpp:4384:57: 'path' is unavailable [\#3097](https://github.com/nlohmann/json/issues/3097) +- GCC 7.5.0 with --std=c++17: filesystem: No such file or directory [\#3090](https://github.com/nlohmann/json/issues/3090) +- Drop Travis CI [\#3087](https://github.com/nlohmann/json/issues/3087) +- ordered\_json::reset\(\) compile error with nvcc [\#3013](https://github.com/nlohmann/json/issues/3013) +- Support for unordered\_map as object\_t [\#2932](https://github.com/nlohmann/json/issues/2932) +- Compiler warning with Intel compiler, same as \#755 [\#2712](https://github.com/nlohmann/json/issues/2712) +- Compiler warnings with NVCC 11.2 [\#2676](https://github.com/nlohmann/json/issues/2676) +- some static analysis warning at line 11317 [\#1390](https://github.com/nlohmann/json/issues/1390) +- Compiling with icpc [\#755](https://github.com/nlohmann/json/issues/755) + +- Fix compilation error with NVCC [\#3234](https://github.com/nlohmann/json/pull/3234) ([nlohmann](https://github.com/nlohmann)) +- Remove Travis CI [\#3233](https://github.com/nlohmann/json/pull/3233) ([nlohmann](https://github.com/nlohmann)) +- Add build step for NVCC and fix a warning [\#3227](https://github.com/nlohmann/json/pull/3227) ([nlohmann](https://github.com/nlohmann)) +- Update cpplint [\#3225](https://github.com/nlohmann/json/pull/3225) ([nlohmann](https://github.com/nlohmann)) +- Fix: Warning for shadowed variables \(\#3188\) [\#3193](https://github.com/nlohmann/json/pull/3193) ([kernie](https://github.com/kernie)) +- Fix FAQ hyperlink typo in readme [\#3148](https://github.com/nlohmann/json/pull/3148) ([Prince-Mendiratta](https://github.com/Prince-Mendiratta)) +- Docs: Update `skip_comments` to `ignore_comments` [\#3145](https://github.com/nlohmann/json/pull/3145) ([daniel-kun](https://github.com/daniel-kun)) +- fix typos in documentation [\#3140](https://github.com/nlohmann/json/pull/3140) ([striezel](https://github.com/striezel)) +- Fix spelling [\#3125](https://github.com/nlohmann/json/pull/3125) ([axic](https://github.com/axic)) +- Extend std specializations [\#3121](https://github.com/nlohmann/json/pull/3121) ([nlohmann](https://github.com/nlohmann)) +- Add missing erase\(first, last\) function to ordered\_map [\#3109](https://github.com/nlohmann/json/pull/3109) ([nlohmann](https://github.com/nlohmann)) +- Fix typos in operator\[\] documentation [\#3102](https://github.com/nlohmann/json/pull/3102) ([axnsan12](https://github.com/axnsan12)) +- Add C++17 copies of the test binaries [\#3101](https://github.com/nlohmann/json/pull/3101) ([nlohmann](https://github.com/nlohmann)) +- Add examples for parsing from iterator pair [\#3100](https://github.com/nlohmann/json/pull/3100) ([nlohmann](https://github.com/nlohmann)) +- Update CI [\#3088](https://github.com/nlohmann/json/pull/3088) ([nlohmann](https://github.com/nlohmann)) +- Consolidate documentation [\#3071](https://github.com/nlohmann/json/pull/3071) ([nlohmann](https://github.com/nlohmann)) +- Add recursive update function [\#3069](https://github.com/nlohmann/json/pull/3069) ([nlohmann](https://github.com/nlohmann)) + +## [v3.10.4](https://github.com/nlohmann/json/releases/tag/v3.10.4) (2021-10-16) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.3...v3.10.4) + +- Compiler error in output serializer due to 'incompatible initializer' [\#3081](https://github.com/nlohmann/json/issues/3081) +- Strange behaviour when using std::sort on std::vector\ [\#3080](https://github.com/nlohmann/json/issues/3080) +- Unhandled exception: nlohmann::detail::parse\_error [\#3078](https://github.com/nlohmann/json/issues/3078) +- explicit constructor with default does not compile [\#3077](https://github.com/nlohmann/json/issues/3077) +- Parse an object but get an array using GCC [\#3076](https://github.com/nlohmann/json/issues/3076) +- Version 3.10.3 breaks backward-compatibility with 3.10.2 [\#3070](https://github.com/nlohmann/json/issues/3070) +- Feature request, Add to\_json/from\_json to align with other to/from binary api. [\#3067](https://github.com/nlohmann/json/issues/3067) +- vcpkg is out of date [\#3066](https://github.com/nlohmann/json/issues/3066) + +- Revert invalid fix [\#3082](https://github.com/nlohmann/json/pull/3082) ([nlohmann](https://github.com/nlohmann)) +- Allow to use get with explicit constructor [\#3079](https://github.com/nlohmann/json/pull/3079) ([nlohmann](https://github.com/nlohmann)) +- fix std::filesystem::path regression [\#3073](https://github.com/nlohmann/json/pull/3073) ([theodelrieu](https://github.com/theodelrieu)) + +## [v3.10.3](https://github.com/nlohmann/json/releases/tag/v3.10.3) (2021-10-08) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.2...v3.10.3) + +- Parsing an emtpy string returns a string with size 1 instead of expected 0 [\#3057](https://github.com/nlohmann/json/issues/3057) +- Linking error "duplicate symbol: std::type\_info::operator==" on static build with MinGW [\#3042](https://github.com/nlohmann/json/issues/3042) +- Yet another assertion failure when inserting into arrays with JSON\_DIAGNOSTICS set [\#3032](https://github.com/nlohmann/json/issues/3032) +- accept and parse function not work well with a pure number string [\#3029](https://github.com/nlohmann/json/issues/3029) +- push\_back doesn't work for serializing containers [\#3027](https://github.com/nlohmann/json/issues/3027) +- Strange behaviour when creating array with single element [\#3025](https://github.com/nlohmann/json/issues/3025) +- Input ordered\_json doesn't work [\#3023](https://github.com/nlohmann/json/issues/3023) +- Issue iterating through 'items' [\#3021](https://github.com/nlohmann/json/issues/3021) +- Cannot spell the namespace right [\#3015](https://github.com/nlohmann/json/issues/3015) +- JSON Parse error when reading json object from file [\#3011](https://github.com/nlohmann/json/issues/3011) +- Parent pointer not properly set when using update\(\) [\#3007](https://github.com/nlohmann/json/issues/3007) +- Overwriting terminated null character [\#3001](https://github.com/nlohmann/json/issues/3001) +- 'operator =' is ambiguous on VS2017 [\#2997](https://github.com/nlohmann/json/issues/2997) +- JSON Patch for Array Elements [\#2994](https://github.com/nlohmann/json/issues/2994) +- JSON Parse throwing error [\#2983](https://github.com/nlohmann/json/issues/2983) +- to\_{binary format} does not provide a mechanism for specifying a custom allocator for the returned type. [\#2982](https://github.com/nlohmann/json/issues/2982) +- 3.10.1 zip json.hpp has version number 3.10.0 instead of 3.10.1 [\#2973](https://github.com/nlohmann/json/issues/2973) +- Assertion failure when serializing array with JSON\_DIAGNOSTICS set [\#2926](https://github.com/nlohmann/json/issues/2926) + +- Fix Clang version [\#3040](https://github.com/nlohmann/json/pull/3040) ([nlohmann](https://github.com/nlohmann)) +- Fix assertion failure for JSON\_DIAGNOSTICS [\#3037](https://github.com/nlohmann/json/pull/3037) ([carlsmedstad](https://github.com/carlsmedstad)) +- meta: fix is\_compatible/constructible traits [\#3020](https://github.com/nlohmann/json/pull/3020) ([theodelrieu](https://github.com/theodelrieu)) +- Set parent pointers for values inserted via update\(\) \(fixes \#3007\). [\#3008](https://github.com/nlohmann/json/pull/3008) ([AnthonyVH](https://github.com/AnthonyVH)) +- Allow allocators for output\_vector\_adapter [\#2989](https://github.com/nlohmann/json/pull/2989) ([nlohmann](https://github.com/nlohmann)) +- Re-add Clang 12 [\#2986](https://github.com/nlohmann/json/pull/2986) ([nlohmann](https://github.com/nlohmann)) +- Use new Docker image [\#2981](https://github.com/nlohmann/json/pull/2981) ([nlohmann](https://github.com/nlohmann)) +- Update docset generation script [\#2967](https://github.com/nlohmann/json/pull/2967) ([nlohmann](https://github.com/nlohmann)) + +## [v3.10.2](https://github.com/nlohmann/json/releases/tag/v3.10.2) (2021-08-26) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.1...v3.10.2) + +- Annoying -Wundef on new JSON\_DIAGNOSTICS macro [\#2975](https://github.com/nlohmann/json/issues/2975) +- += issue with multiple redirection. [\#2970](https://github.com/nlohmann/json/issues/2970) +- "incomplete type ‘nlohmann::detail::wide\_string\_input\_helper" compilation error [\#2969](https://github.com/nlohmann/json/issues/2969) + +- Fix -Wunused warnings on JSON\_DIAGNOSTICS [\#2976](https://github.com/nlohmann/json/pull/2976) ([gcerretani](https://github.com/gcerretani)) + +## [v3.10.1](https://github.com/nlohmann/json/releases/tag/v3.10.1) (2021-08-24) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.0...v3.10.1) + +- JSON\_DIAGNOSTICS assertion for ordered\_json [\#2962](https://github.com/nlohmann/json/issues/2962) +- Inserting in unordered json using a pointer retains the leading slash [\#2958](https://github.com/nlohmann/json/issues/2958) +- Test \#9: test-cbor test case sample.json fails in debug mode - Stack overflow [\#2955](https://github.com/nlohmann/json/issues/2955) +- 3.10.0 broke at least the Bear project [\#2953](https://github.com/nlohmann/json/issues/2953) +- 2 tests fail in 3.10.0: cmake\_fetch\_content\_configure, cmake\_fetch\_content\_build [\#2951](https://github.com/nlohmann/json/issues/2951) +- ctest \(58+60,/67 cmake\_import\_configure\) fails when build with -D JSON\_Install:BOOL=OFF because of missing nlohmann\_jsonTargets.cmake [\#2946](https://github.com/nlohmann/json/issues/2946) +- Document vcpkg usage [\#2944](https://github.com/nlohmann/json/issues/2944) +- Linker error LNK2005 when compiling \(x64\) json-3.10.0.zip with Visual Studio 2019 16.11.1 [\#2941](https://github.com/nlohmann/json/issues/2941) +- Move Travis jobs to travis-ci.com [\#2938](https://github.com/nlohmann/json/issues/2938) + +- Fixed typo in docs/api/basic\_json/parse.md [\#2968](https://github.com/nlohmann/json/pull/2968) ([mbadhan](https://github.com/mbadhan)) +- Add link to Homebrew package [\#2966](https://github.com/nlohmann/json/pull/2966) ([nlohmann](https://github.com/nlohmann)) +- Fix parent update for diagnostics with ordered\_json [\#2963](https://github.com/nlohmann/json/pull/2963) ([nlohmann](https://github.com/nlohmann)) +- Set stack size for some unit tests when using MSVC [\#2961](https://github.com/nlohmann/json/pull/2961) ([nlohmann](https://github.com/nlohmann)) +- Add regression test [\#2960](https://github.com/nlohmann/json/pull/2960) ([nlohmann](https://github.com/nlohmann)) +- Update Travis badge [\#2959](https://github.com/nlohmann/json/pull/2959) ([nlohmann](https://github.com/nlohmann)) +- Fix some extra ";" clang warnings [\#2957](https://github.com/nlohmann/json/pull/2957) ([Hallot](https://github.com/Hallot)) +- Add documentation for integration via vcpkg [\#2954](https://github.com/nlohmann/json/pull/2954) ([nlohmann](https://github.com/nlohmann)) +- Avoid duplicate AppVeyor builds [\#2952](https://github.com/nlohmann/json/pull/2952) ([nlohmann](https://github.com/nlohmann)) +- 🚨 fix gdb\_pretty\_printer failure on basic types [\#2950](https://github.com/nlohmann/json/pull/2950) ([senyai](https://github.com/senyai)) +- Add header to use value\_t [\#2948](https://github.com/nlohmann/json/pull/2948) ([nlohmann](https://github.com/nlohmann)) +- Skip some tests if JSON\_Install is not set [\#2947](https://github.com/nlohmann/json/pull/2947) ([nlohmann](https://github.com/nlohmann)) +- Remove outdated json\_unit test binary [\#2945](https://github.com/nlohmann/json/pull/2945) ([nlohmann](https://github.com/nlohmann)) +- Updating the Homebrew Command [\#2943](https://github.com/nlohmann/json/pull/2943) ([amirmasoudabdol](https://github.com/amirmasoudabdol)) + +## [v3.10.0](https://github.com/nlohmann/json/releases/tag/v3.10.0) (2021-08-17) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.9.1...v3.10.0) + +- Latest version 3.9.1 uses throw instead of JSON\_THROW in the amalgamated json.hpp file [\#2934](https://github.com/nlohmann/json/issues/2934) +- Copy to a variable inside a Structure [\#2933](https://github.com/nlohmann/json/issues/2933) +- warning C4068: unknown pragma 'GCC' on MSVC/cl [\#2924](https://github.com/nlohmann/json/issues/2924) +- Errors during ninja test [\#2918](https://github.com/nlohmann/json/issues/2918) +- compiler warning: "not return a value" [\#2917](https://github.com/nlohmann/json/issues/2917) +- Comparison floating points causes warning [\#2909](https://github.com/nlohmann/json/issues/2909) +- Why can't I have std::vector\ testList? [\#2900](https://github.com/nlohmann/json/issues/2900) +- \[json.hpp\] from releases doesnt work [\#2897](https://github.com/nlohmann/json/issues/2897) +- g++ \(11\) -Wuseless-cast gives lots of warnings [\#2893](https://github.com/nlohmann/json/issues/2893) +- Cannot serialize and immediatly deserialize json to/from bson [\#2892](https://github.com/nlohmann/json/issues/2892) +- Floating-point precision conversion error [\#2876](https://github.com/nlohmann/json/issues/2876) +- How to avoid escaping for an already escaped string in .dump\(\) [\#2870](https://github.com/nlohmann/json/issues/2870) +- can't parse std::vector\ [\#2869](https://github.com/nlohmann/json/issues/2869) +- ASAN detects memory leaks [\#2865](https://github.com/nlohmann/json/issues/2865) +- Binary subtype field cannot represent all CBOR tags [\#2863](https://github.com/nlohmann/json/issues/2863) +- string literals possibly being parsed as another type due to the presence of only digits and full-stops [\#2852](https://github.com/nlohmann/json/issues/2852) +- json::parse\(\) works only with absolute paths [\#2851](https://github.com/nlohmann/json/issues/2851) +- Compiler Warnings on Raspberry Pi OS [\#2850](https://github.com/nlohmann/json/issues/2850) +- Braced initialization and aggregate initialization behavior is different for `json::array()` function call. [\#2848](https://github.com/nlohmann/json/issues/2848) +- 3.9.1: test suite is failing [\#2845](https://github.com/nlohmann/json/issues/2845) +- Documentation for macro JSON\_NO\_IO is missing [\#2842](https://github.com/nlohmann/json/issues/2842) +- Assertion failure when inserting into arrays with JSON\_DIAGNOSTICS set [\#2838](https://github.com/nlohmann/json/issues/2838) +- HELP! There is a memory leak in the code?! [\#2837](https://github.com/nlohmann/json/issues/2837) +- Elegant conversion of a 2-D-json array to a standard C++ array [\#2805](https://github.com/nlohmann/json/issues/2805) +- Swift Package Manager support [\#2802](https://github.com/nlohmann/json/issues/2802) +- Referencing a subkey which doesn't exist gives crash [\#2797](https://github.com/nlohmann/json/issues/2797) +- Failed benchmark due to renamed branch [\#2796](https://github.com/nlohmann/json/issues/2796) +- Build Errors with VS 2019 and json Version 3.9.1 when attempting to replicate SAX Example [\#2782](https://github.com/nlohmann/json/issues/2782) +- Value with spaces cannot be parsed [\#2781](https://github.com/nlohmann/json/issues/2781) +- \[Question\] CBOR rfc support. [\#2779](https://github.com/nlohmann/json/issues/2779) +- Using JSON.hpp header file in Visual Studio 2013 \(C++ Project\) [\#2775](https://github.com/nlohmann/json/issues/2775) +- compilation error on clang-8 + C++17 [\#2759](https://github.com/nlohmann/json/issues/2759) +- Undefined symbol EOF [\#2755](https://github.com/nlohmann/json/issues/2755) +- Parsing a string into json object behaves differently under g++ and MinGW compilers. [\#2746](https://github.com/nlohmann/json/issues/2746) +- big git history size [\#2742](https://github.com/nlohmann/json/issues/2742) +- How to get reference of std::vector\ [\#2735](https://github.com/nlohmann/json/issues/2735) +- CMake failure in VS2019 Community [\#2734](https://github.com/nlohmann/json/issues/2734) +- Possibility to use with custom c++ version to use in intel sgx enclaves [\#2730](https://github.com/nlohmann/json/issues/2730) +- Possibility to use without the dependency to file io and streams to use in intel sgx enclaves [\#2728](https://github.com/nlohmann/json/issues/2728) +- error C2784& error C2839... in my visual studio 2015 compiler [\#2726](https://github.com/nlohmann/json/issues/2726) +- `-fno-expection` not respected anymore in 3.9.1 [\#2725](https://github.com/nlohmann/json/issues/2725) +- When exceptions disabled with JSON\_NOEXCEPTION, lib just aborts without any message [\#2724](https://github.com/nlohmann/json/issues/2724) +- Critical error detected c0000374 on windows10 msvc 2019 16.8.5 [\#2710](https://github.com/nlohmann/json/issues/2710) +- unused parameter error/warning [\#2706](https://github.com/nlohmann/json/issues/2706) +- How to store data into a Map from json file [\#2691](https://github.com/nlohmann/json/issues/2691) +- Tests do not compile with pre-release glibc [\#2686](https://github.com/nlohmann/json/issues/2686) +- compile errors .... chromium-style [\#2680](https://github.com/nlohmann/json/issues/2680) +- .dump\(\) not allowing compact form [\#2678](https://github.com/nlohmann/json/issues/2678) +- error: no matching function for call to ‘nlohmann::basic\_json\<\>::value\(int, std::set\&\)’ [\#2671](https://github.com/nlohmann/json/issues/2671) +- Compiler warning: unused parameter [\#2668](https://github.com/nlohmann/json/issues/2668) +- Deserializing to a struct as shown on the project homepage throws compile time errors [\#2665](https://github.com/nlohmann/json/issues/2665) +- Unable to compile on MSVC 2019 with SDL checking enabled: This function or variable may be unsafe [\#2664](https://github.com/nlohmann/json/issues/2664) +- terminating with uncaught exception of type nlohmann::detail::type\_error: \[json.exception.type\_error.302\] type must be array, but is object [\#2661](https://github.com/nlohmann/json/issues/2661) +- unused-parameter on OSX when Diagnostics is off [\#2658](https://github.com/nlohmann/json/issues/2658) +- std::pair wrong serialization [\#2655](https://github.com/nlohmann/json/issues/2655) +- The result of json is\_number\_integer\(\) function is wrong when read a json file [\#2653](https://github.com/nlohmann/json/issues/2653) +- 2 backslash cause problem [\#2652](https://github.com/nlohmann/json/issues/2652) +- No support for using an external/system copy of Hedley [\#2651](https://github.com/nlohmann/json/issues/2651) +- error: incomplete type 'qfloat16' used in type trait expression [\#2650](https://github.com/nlohmann/json/issues/2650) +- Unused variable in exception class when not using improved diagnostics [\#2646](https://github.com/nlohmann/json/issues/2646) +- I am trying to do this - converting from wstring works incorrectly! [\#2642](https://github.com/nlohmann/json/issues/2642) +- Exception 207 On ARM Processor During Literal String Parsing [\#2634](https://github.com/nlohmann/json/issues/2634) +- double free or corruption \(!prev\) error on Json push\_back and write [\#2632](https://github.com/nlohmann/json/issues/2632) +- nlohmann::detail::parse\_error: syntax error while parsing CBOR string: expected length specification \(0x60-0x7B\) or indefinite string type \(0x7F\) [\#2629](https://github.com/nlohmann/json/issues/2629) +- please allow disabling implicit conversions in non-single-file use [\#2621](https://github.com/nlohmann/json/issues/2621) +- Preserve decimal formatting [\#2618](https://github.com/nlohmann/json/issues/2618) +- Visual Studio Visual Assist code issues reported by VA code inspection of file json.hpp [\#2615](https://github.com/nlohmann/json/issues/2615) +- Missing get function and no viable overloaded '=' on mac [\#2610](https://github.com/nlohmann/json/issues/2610) +- corruption when parse from string [\#2603](https://github.com/nlohmann/json/issues/2603) +- Parse from byte-vector results in compile error [\#2602](https://github.com/nlohmann/json/issues/2602) +- Memory leak when working on ARM Linux [\#2601](https://github.com/nlohmann/json/issues/2601) +- Unhandled exception in test-cbor.exe Stack overflow when debugging project with Visual Studio 2019 16.7.7 compiled with c++17 or c++latest [\#2598](https://github.com/nlohmann/json/issues/2598) +- Error in download\_test\_data.vcxproj when compiling with Visual Studio 2019 16.7.7 Professional msbuild on Windows 10 2004 Professional [\#2594](https://github.com/nlohmann/json/issues/2594) +- Warnings C4715 and C4127 when building json-3.9.1 with Visual Studio 2019 16.7.7 [\#2592](https://github.com/nlohmann/json/issues/2592) +- I tried some change to dump\(\) for \[1,2,3...\] [\#2584](https://github.com/nlohmann/json/issues/2584) +- try/catch block does not catch parsing error [\#2579](https://github.com/nlohmann/json/issues/2579) +- Serializing uint64\_t is broken for large values [\#2578](https://github.com/nlohmann/json/issues/2578) +- deserializing arrays should be part of the library [\#2575](https://github.com/nlohmann/json/issues/2575) +- Deserialization to std::array with non-default constructable types fails [\#2574](https://github.com/nlohmann/json/issues/2574) +- Compilation error when trying to use same type for number\_integer\_t and number\_unsigned\_t in basic\_json template specification. [\#2573](https://github.com/nlohmann/json/issues/2573) +- compiler error: directive output may be truncated writing between 2 and 8 bytes [\#2572](https://github.com/nlohmann/json/issues/2572) +- Incorrect convert map to json when key cannot construct an string i.e. int [\#2564](https://github.com/nlohmann/json/issues/2564) +- no matching function for call to ‘nlohmann::basic\_json\<\>::basic\_json\(\\)’ [\#2559](https://github.com/nlohmann/json/issues/2559) +- type\_error factory creates a dangling pointer \(in VisualStudio 2019\) [\#2535](https://github.com/nlohmann/json/issues/2535) +- Cannot assign from ordered\_json vector\ to value in not ordered json [\#2528](https://github.com/nlohmann/json/issues/2528) +- Qt6: Break changes [\#2519](https://github.com/nlohmann/json/issues/2519) +- valgrind memcheck Illegal instruction when use nlohmann::json::parse [\#2518](https://github.com/nlohmann/json/issues/2518) +- Buffer overflow [\#2515](https://github.com/nlohmann/json/issues/2515) +- Including CTest in the top-level CMakeLists.txt sets BUILD\_TESTING=ON for parent projects [\#2513](https://github.com/nlohmann/json/issues/2513) +- Compilation error when using NLOHMANN\_JSON\_SERIALIZE\_ENUM ordered\_json on libc++ [\#2491](https://github.com/nlohmann/json/issues/2491) +- Missing "void insert\( InputIt first, InputIt last \);" overload in nlohmann::ordered\_map [\#2490](https://github.com/nlohmann/json/issues/2490) +- Could not find a package configuration file provided by "nlohmann\_json" [\#2482](https://github.com/nlohmann/json/issues/2482) +- json becomes empty for unknown reason [\#2470](https://github.com/nlohmann/json/issues/2470) +- Using std::wstring as StringType fails compiling [\#2459](https://github.com/nlohmann/json/issues/2459) +- Sample code in GIF slide outdated \(cannot use emplace\(\) with array\) [\#2457](https://github.com/nlohmann/json/issues/2457) +- from\_json\ is treated as an array on latest MSVC [\#2453](https://github.com/nlohmann/json/issues/2453) +- MemorySanitizer: use-of-uninitialized-value [\#2449](https://github.com/nlohmann/json/issues/2449) +- I need help [\#2441](https://github.com/nlohmann/json/issues/2441) +- type conversion failing with clang ext\_vector\_type [\#2436](https://github.com/nlohmann/json/issues/2436) +- json::parse\(\) can't be resolved under specific circumstances [\#2427](https://github.com/nlohmann/json/issues/2427) +- from\_\*\(ptr, len\) deprecation [\#2426](https://github.com/nlohmann/json/issues/2426) +- Error ONLY in release mode [\#2425](https://github.com/nlohmann/json/issues/2425) +- "Custom data source" exemple make no sense [\#2423](https://github.com/nlohmann/json/issues/2423) +- Refuses to compile in project [\#2419](https://github.com/nlohmann/json/issues/2419) +- Compilation failure of tests with C++20 standard \(caused by change of u8 literals\) [\#2413](https://github.com/nlohmann/json/issues/2413) +- No matching function for call to 'input\_adapter' under Xcode of with nlohmann version 3.9.1 [\#2412](https://github.com/nlohmann/json/issues/2412) +- Git tags are not valid semvers [\#2409](https://github.com/nlohmann/json/issues/2409) +- after dump, stderr output disappear [\#2403](https://github.com/nlohmann/json/issues/2403) +- Using custom string. [\#2398](https://github.com/nlohmann/json/issues/2398) +- value\(\) throws unhandled exception for partially specified json object [\#2393](https://github.com/nlohmann/json/issues/2393) +- assertion on runtime causes program to stop when accessing const json with missing key [\#2392](https://github.com/nlohmann/json/issues/2392) +- Usage with -fno-elide-constructors causes dump\(\) output to be array of `null`s [\#2387](https://github.com/nlohmann/json/issues/2387) +- Build fails with clang-cl due to override of CMAKE\_CXX\_COMPILER\(?\) [\#2384](https://github.com/nlohmann/json/issues/2384) +- std::optional not working with primitive types [\#2383](https://github.com/nlohmann/json/issues/2383) +- Unexpected array when initializing a json const& on gcc 4.8.5 using uniform syntax [\#2370](https://github.com/nlohmann/json/issues/2370) +- setprecision support [\#2362](https://github.com/nlohmann/json/issues/2362) +- json::parse\(allow\_exceptions = false\) documentation is misleading. [\#2360](https://github.com/nlohmann/json/issues/2360) +- std::begin and std::end usage without specifying std namespace [\#2359](https://github.com/nlohmann/json/issues/2359) +- Custom object conversion to json hangs in background thread [\#2358](https://github.com/nlohmann/json/issues/2358) +- Add support of nullable fields to NLOHMANN\_DEFINE\_TYPE\_NON\_INTRUSIVE and NLOHMANN\_DEFINE\_TYPE\_INTRUSIVE [\#2356](https://github.com/nlohmann/json/issues/2356) +- the portfile for the vcpkg is not working. [\#2351](https://github.com/nlohmann/json/issues/2351) +- Compiler warns of implicit fallthrough when defining preprocessor macro NDEBUG [\#2348](https://github.com/nlohmann/json/issues/2348) +- Compile error on Intel compiler running in Windows [\#2346](https://github.com/nlohmann/json/issues/2346) +- Build error caused by overwriting CMAKE\_CXX\_COMPILER [\#2343](https://github.com/nlohmann/json/issues/2343) +- Error: an attribute list cannot appear here JSON\_HEDLEY\_DEPRECATED\_FOR [\#2342](https://github.com/nlohmann/json/issues/2342) +- compiler warning [\#2341](https://github.com/nlohmann/json/issues/2341) +- 3.9.0: tests make build non-reproducible [\#2324](https://github.com/nlohmann/json/issues/2324) +- Initialization different between gcc/clang [\#2311](https://github.com/nlohmann/json/issues/2311) +- Attempt to `get()` a numeric value as a type which cannot represent it should throw [\#2310](https://github.com/nlohmann/json/issues/2310) +- Surprising behaviour with overloaded operators [\#2256](https://github.com/nlohmann/json/issues/2256) +- ADL issue in input\_adapter [\#2248](https://github.com/nlohmann/json/issues/2248) +- Output adapters should be templated. [\#2172](https://github.com/nlohmann/json/issues/2172) +- error when using nlohmann::json, std::function and std::bind [\#2147](https://github.com/nlohmann/json/issues/2147) +- Remove undefined behavior for const operator\[\] [\#2111](https://github.com/nlohmann/json/issues/2111) +- json\({}\) gives null instead of empty object with GCC and -std=c++17 [\#2046](https://github.com/nlohmann/json/issues/2046) +- GDB pretty printing support [\#1952](https://github.com/nlohmann/json/issues/1952) +- Always compile tests with all warnings enabled and error out on warnings [\#1798](https://github.com/nlohmann/json/issues/1798) +- Fixes Cppcheck warnings [\#1759](https://github.com/nlohmann/json/issues/1759) +- How to get position info or parser context with custom from\_json\(\) that may throw exceptions? [\#1508](https://github.com/nlohmann/json/issues/1508) +- Suggestion to improve value\(\) accessors with respect to move semantics [\#1275](https://github.com/nlohmann/json/issues/1275) +- Add Key name to Exception [\#932](https://github.com/nlohmann/json/issues/932) + +- Overwork warning flags [\#2936](https://github.com/nlohmann/json/pull/2936) ([nlohmann](https://github.com/nlohmann)) +- Treat MSVC warnings as errors [\#2930](https://github.com/nlohmann/json/pull/2930) ([nlohmann](https://github.com/nlohmann)) +- All: fix warnings when compiling with -Wswitch-enum [\#2927](https://github.com/nlohmann/json/pull/2927) ([fhuberts](https://github.com/fhuberts)) +- Guard GCC pragmas [\#2925](https://github.com/nlohmann/json/pull/2925) ([nlohmann](https://github.com/nlohmann)) +- Supress -Wfloat-equal on intended float comparisions [\#2911](https://github.com/nlohmann/json/pull/2911) ([Finkman](https://github.com/Finkman)) +- Fix binary subtypes [\#2908](https://github.com/nlohmann/json/pull/2908) ([nlohmann](https://github.com/nlohmann)) +- Fix useless-cast warnings [\#2902](https://github.com/nlohmann/json/pull/2902) ([nlohmann](https://github.com/nlohmann)) +- Add regression test [\#2898](https://github.com/nlohmann/json/pull/2898) ([nlohmann](https://github.com/nlohmann)) +- Refactor Unicode tests [\#2889](https://github.com/nlohmann/json/pull/2889) ([nlohmann](https://github.com/nlohmann)) +- CMake cleanup [\#2885](https://github.com/nlohmann/json/pull/2885) ([nlohmann](https://github.com/nlohmann)) +- Avoid string in case of empty CBOR objects [\#2879](https://github.com/nlohmann/json/pull/2879) ([nlohmann](https://github.com/nlohmann)) +- Suppress C4127 warning in unit-json\_pointer.cpp [\#2875](https://github.com/nlohmann/json/pull/2875) ([nlohmann](https://github.com/nlohmann)) +- Fix truncation warning [\#2874](https://github.com/nlohmann/json/pull/2874) ([nlohmann](https://github.com/nlohmann)) +- Fix memory leak in to\_json [\#2872](https://github.com/nlohmann/json/pull/2872) ([nlohmann](https://github.com/nlohmann)) +- Fix assertion failure in diagnostics [\#2866](https://github.com/nlohmann/json/pull/2866) ([nlohmann](https://github.com/nlohmann)) +- Update documentation [\#2861](https://github.com/nlohmann/json/pull/2861) ([nlohmann](https://github.com/nlohmann)) +- Consistency with `using` in README.md [\#2826](https://github.com/nlohmann/json/pull/2826) ([justanotheranonymoususer](https://github.com/justanotheranonymoususer)) +- Properly constrain the basic\_json conversion operator [\#2825](https://github.com/nlohmann/json/pull/2825) ([ldionne](https://github.com/ldionne)) +- Fix CI [\#2817](https://github.com/nlohmann/json/pull/2817) ([nlohmann](https://github.com/nlohmann)) +- Specified git branch for google benchmark fetch in benchmark test [\#2795](https://github.com/nlohmann/json/pull/2795) ([grafail](https://github.com/grafail)) +- Add C++ standards to macOS matrix [\#2790](https://github.com/nlohmann/json/pull/2790) ([nlohmann](https://github.com/nlohmann)) +- Update URLs to HTTPS [\#2789](https://github.com/nlohmann/json/pull/2789) ([TotalCaesar659](https://github.com/TotalCaesar659)) +- Link to Conan Center package added [\#2771](https://github.com/nlohmann/json/pull/2771) ([offa](https://github.com/offa)) +- Keep consistent formatting [\#2770](https://github.com/nlohmann/json/pull/2770) ([jasmcaus](https://github.com/jasmcaus)) +- Add a cmake option to use SYSTEM in target\_include\_directories [\#2762](https://github.com/nlohmann/json/pull/2762) ([jpl-mac](https://github.com/jpl-mac)) +- replace EOF with std::char\_traits\::eof\(\) [\#2756](https://github.com/nlohmann/json/pull/2756) ([nlohmann](https://github.com/nlohmann)) +- Fix typo in README [\#2754](https://github.com/nlohmann/json/pull/2754) ([mortenfyhn](https://github.com/mortenfyhn)) +- Update documentation [\#2749](https://github.com/nlohmann/json/pull/2749) ([nlohmann](https://github.com/nlohmann)) +- Add documentation for numbers [\#2747](https://github.com/nlohmann/json/pull/2747) ([nlohmann](https://github.com/nlohmann)) +- Use Clang 12 in CI [\#2737](https://github.com/nlohmann/json/pull/2737) ([nlohmann](https://github.com/nlohmann)) +- Fixes \#2730 [\#2731](https://github.com/nlohmann/json/pull/2731) ([theShmoo](https://github.com/theShmoo)) +- Possibility to use without the dependency to file io and streams to use in intel sgx enclaves [\#2729](https://github.com/nlohmann/json/pull/2729) ([theShmoo](https://github.com/theShmoo)) +- Update json.hpp [\#2707](https://github.com/nlohmann/json/pull/2707) ([raduteo](https://github.com/raduteo)) +- pkg-config.pc.in: Don't concatenate paths [\#2690](https://github.com/nlohmann/json/pull/2690) ([doronbehar](https://github.com/doronbehar)) +- add more CI steps [\#2689](https://github.com/nlohmann/json/pull/2689) ([nlohmann](https://github.com/nlohmann)) +- Update doctest from 2.4.4 to 2.4.6 \(fixes \#2686\) [\#2687](https://github.com/nlohmann/json/pull/2687) ([musicinmybrain](https://github.com/musicinmybrain)) +- License fix [\#2683](https://github.com/nlohmann/json/pull/2683) ([nlohmann](https://github.com/nlohmann)) +- Update parse\_exceptions.md - correct `json::exception::parse_error` [\#2679](https://github.com/nlohmann/json/pull/2679) ([frasermarlow](https://github.com/frasermarlow)) +- Remove HEDLEY annotation from exception::what\(\) [\#2673](https://github.com/nlohmann/json/pull/2673) ([remyjette](https://github.com/remyjette)) +- Fix amount of entries in the json object [\#2659](https://github.com/nlohmann/json/pull/2659) ([abbaswasim](https://github.com/abbaswasim)) +- Fix missing 1.78 in example in README.md [\#2625](https://github.com/nlohmann/json/pull/2625) ([wawiesel](https://github.com/wawiesel)) +- Add GDB pretty printer [\#2607](https://github.com/nlohmann/json/pull/2607) ([nlohmann](https://github.com/nlohmann)) +- readme: fix tilde character display [\#2582](https://github.com/nlohmann/json/pull/2582) ([bl-ue](https://github.com/bl-ue)) +- Add support for deserialization of STL containers of non-default constructable types \(fixes \#2574\). [\#2576](https://github.com/nlohmann/json/pull/2576) ([AnthonyVH](https://github.com/AnthonyVH)) +- Better diagnostics [\#2562](https://github.com/nlohmann/json/pull/2562) ([nlohmann](https://github.com/nlohmann)) +- CI targets [\#2561](https://github.com/nlohmann/json/pull/2561) ([nlohmann](https://github.com/nlohmann)) +- Add switch to skip non-reproducible tests. [\#2560](https://github.com/nlohmann/json/pull/2560) ([nlohmann](https://github.com/nlohmann)) +- Fix compilation of input\_adapter\(container\) in edge cases [\#2553](https://github.com/nlohmann/json/pull/2553) ([jasujm](https://github.com/jasujm)) +- Allow parsing from std::byte containers [\#2550](https://github.com/nlohmann/json/pull/2550) ([nlohmann](https://github.com/nlohmann)) +- Travis doesn't run any tests in C++17 mode [\#2540](https://github.com/nlohmann/json/pull/2540) ([karzhenkov](https://github.com/karzhenkov)) +- Doctest is updated to v2.4.3 [\#2538](https://github.com/nlohmann/json/pull/2538) ([YarikTH](https://github.com/YarikTH)) +- Fix warnings [\#2537](https://github.com/nlohmann/json/pull/2537) ([nlohmann](https://github.com/nlohmann)) +- Fix a shadowing warning [\#2536](https://github.com/nlohmann/json/pull/2536) ([nlohmann](https://github.com/nlohmann)) +- Clarify license of is\_complete\_type implementation [\#2534](https://github.com/nlohmann/json/pull/2534) ([nlohmann](https://github.com/nlohmann)) +- Do not unconditionally redefine C++14 constructs [\#2533](https://github.com/nlohmann/json/pull/2533) ([nlohmann](https://github.com/nlohmann)) +- Doctest is updated to v2.4.1 [\#2525](https://github.com/nlohmann/json/pull/2525) ([YarikTH](https://github.com/YarikTH)) +- Add MAIN\_PROJECT check for test and install options [\#2514](https://github.com/nlohmann/json/pull/2514) ([globberwops](https://github.com/globberwops)) +- Ranged insert test section is added in unit-ordered\_json.cpp [\#2512](https://github.com/nlohmann/json/pull/2512) ([YarikTH](https://github.com/YarikTH)) +- Add asserts to suppress C28020 [\#2447](https://github.com/nlohmann/json/pull/2447) ([jbzdarkid](https://github.com/jbzdarkid)) +- Change argument name "subtype" in byte\_container\_with\_subtype [\#2444](https://github.com/nlohmann/json/pull/2444) ([linev](https://github.com/linev)) +- 📝 add CPM.Cmake example [\#2406](https://github.com/nlohmann/json/pull/2406) ([leozz37](https://github.com/leozz37)) +- Fix move constructor of json\_ref [\#2405](https://github.com/nlohmann/json/pull/2405) ([karzhenkov](https://github.com/karzhenkov)) +- Properly select "Release" build for Travis [\#2375](https://github.com/nlohmann/json/pull/2375) ([karzhenkov](https://github.com/karzhenkov)) +- Update Hedley [\#2367](https://github.com/nlohmann/json/pull/2367) ([nlohmann](https://github.com/nlohmann)) +- Fix and extend documentation of discarded values [\#2363](https://github.com/nlohmann/json/pull/2363) ([nlohmann](https://github.com/nlohmann)) +- Fix typos in documentation [\#2354](https://github.com/nlohmann/json/pull/2354) ([rbuch](https://github.com/rbuch)) +- Remove "\#define private public" from tests [\#2352](https://github.com/nlohmann/json/pull/2352) ([nlohmann](https://github.com/nlohmann)) +- Remove -Wimplicit-fallthrough warning [\#2349](https://github.com/nlohmann/json/pull/2349) ([nlohmann](https://github.com/nlohmann)) +- Fix code to work without exceptions [\#2347](https://github.com/nlohmann/json/pull/2347) ([nlohmann](https://github.com/nlohmann)) +- fix cmake script overwriting compiler path [\#2344](https://github.com/nlohmann/json/pull/2344) ([ongjunjie](https://github.com/ongjunjie)) + +## [v3.9.1](https://github.com/nlohmann/json/releases/tag/v3.9.1) (2020-08-06) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.9.0...v3.9.1) + +- Can't parse not formatted JSON. [\#2340](https://github.com/nlohmann/json/issues/2340) +- parse returns desired array contained in array when JSON text begins with square bracket on gcc 7.5.0 [\#2339](https://github.com/nlohmann/json/issues/2339) +- Unexpected deserialization difference between Mac and Linux [\#2338](https://github.com/nlohmann/json/issues/2338) +- Reading ordered\_json from file causes compile error [\#2331](https://github.com/nlohmann/json/issues/2331) +- ignore\_comment=true fails on multiple consecutive lines starting with comments [\#2330](https://github.com/nlohmann/json/issues/2330) +- Update documentation about Homebrew installation and CMake integration - Homebrew [\#2326](https://github.com/nlohmann/json/issues/2326) +- Chinese character initialize error [\#2325](https://github.com/nlohmann/json/issues/2325) +- json.update and vector\does not work with ordered\_json [\#2315](https://github.com/nlohmann/json/issues/2315) +- Ambiguous call to overloaded function [\#2210](https://github.com/nlohmann/json/issues/2210) + +- Fix fallthrough warning [\#2333](https://github.com/nlohmann/json/pull/2333) ([nlohmann](https://github.com/nlohmann)) +- Fix lexer to properly cope with repeated comments [\#2332](https://github.com/nlohmann/json/pull/2332) ([nlohmann](https://github.com/nlohmann)) +- Fix name of Homebrew formula in documentation [\#2327](https://github.com/nlohmann/json/pull/2327) ([nlohmann](https://github.com/nlohmann)) +- fix typo [\#2320](https://github.com/nlohmann/json/pull/2320) ([wx257osn2](https://github.com/wx257osn2)) +- Fix a bug due to missing overloads in ordered\_map container [\#2319](https://github.com/nlohmann/json/pull/2319) ([nlohmann](https://github.com/nlohmann)) +- cmake: install pkg-config file relative to current\_binary\_dir [\#2318](https://github.com/nlohmann/json/pull/2318) ([eli-schwartz](https://github.com/eli-schwartz)) +- Fixed installation of pkg-config file on other than Ubuntu [\#2314](https://github.com/nlohmann/json/pull/2314) ([xvitaly](https://github.com/xvitaly)) + +## [v3.9.0](https://github.com/nlohmann/json/releases/tag/v3.9.0) (2020-07-27) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.8.0...v3.9.0) + +- Unknown Type Name clang error when using NLOHMANN\_DEFINE\_TYPE\_NON\_INTRUSIVE [\#2313](https://github.com/nlohmann/json/issues/2313) +- Clang 10.0 / GCC 10.1 warnings on disabled exceptions [\#2304](https://github.com/nlohmann/json/issues/2304) +- Application stalls indefinitely with message byte size 10 [\#2293](https://github.com/nlohmann/json/issues/2293) +- linker error [\#2292](https://github.com/nlohmann/json/issues/2292) +- Add support for high-precision numbers in UBJSON encoding [\#2286](https://github.com/nlohmann/json/issues/2286) +- NLOHMANN\_DEFINE\_TYPE\_NON\_INTRUSIVE fails if the length of the argument is 10 [\#2280](https://github.com/nlohmann/json/issues/2280) +- Custom types : MACRO expansion bug [\#2267](https://github.com/nlohmann/json/issues/2267) +- to/from\_json Failing To Convert String [\#2238](https://github.com/nlohmann/json/issues/2238) +- clang 9.0 report warning: unused type alias 'size\_type' \[-Wunused-local-typedef\] [\#2221](https://github.com/nlohmann/json/issues/2221) +- Enormous array created when working with map\ [\#2220](https://github.com/nlohmann/json/issues/2220) +- Can I disable sorting of json values [\#2219](https://github.com/nlohmann/json/issues/2219) +- Getting Qt types to work [\#2217](https://github.com/nlohmann/json/issues/2217) +- Convert to Qt QVariant [\#2216](https://github.com/nlohmann/json/issues/2216) +- How to custom serialize same data type of vector? [\#2215](https://github.com/nlohmann/json/issues/2215) +- json constructor does not support std::optional [\#2214](https://github.com/nlohmann/json/issues/2214) +- Failing to Parse Valid JSON [\#2209](https://github.com/nlohmann/json/issues/2209) +- \(De-\)Serialization of std::variant with namespaces [\#2208](https://github.com/nlohmann/json/issues/2208) +- Addint support for complex type [\#2207](https://github.com/nlohmann/json/issues/2207) +- array\_index possible out of range [\#2205](https://github.com/nlohmann/json/issues/2205) +- Object deserialized as array [\#2204](https://github.com/nlohmann/json/issues/2204) +- Sending to a function a reference to a sub-branch [\#2200](https://github.com/nlohmann/json/issues/2200) +- How to Serialize derived class to JSON object? [\#2199](https://github.com/nlohmann/json/issues/2199) +- JSON incorrectly serialized [\#2198](https://github.com/nlohmann/json/issues/2198) +- Exception Unhandled out\_of\_range error [\#2197](https://github.com/nlohmann/json/issues/2197) +- msgpack serialisation : float is treated as 64bit float, not 32bit float. [\#2196](https://github.com/nlohmann/json/issues/2196) +- Is it possible to use compile-time type guarantees for JSON structures? [\#2195](https://github.com/nlohmann/json/issues/2195) +- Question : performance against python dict [\#2194](https://github.com/nlohmann/json/issues/2194) +- vs2017 compile error [\#2192](https://github.com/nlohmann/json/issues/2192) +- Check if a key exists [\#2191](https://github.com/nlohmann/json/issues/2191) +- Failed to run tests due to missing test data on builders without Internet access [\#2190](https://github.com/nlohmann/json/issues/2190) +- 3.8.0: unit-cbor.cpp test failures [\#2189](https://github.com/nlohmann/json/issues/2189) +- 'nlohmann/json.hpp' file not found [\#2188](https://github.com/nlohmann/json/issues/2188) +- How to send json data over the wire? [\#2185](https://github.com/nlohmann/json/issues/2185) +- Ubuntu 16 not supporting nlohmann/json? [\#2184](https://github.com/nlohmann/json/issues/2184) +- .get\ causing emdash errors [\#2180](https://github.com/nlohmann/json/issues/2180) +- Object properties should not be re-sorted alphabetically [\#2179](https://github.com/nlohmann/json/issues/2179) +- Custom type registration : instrusive API [\#2175](https://github.com/nlohmann/json/issues/2175) +- Many version of the function "void to\_json\(json& j, const MyStruct& struct\)" [\#2171](https://github.com/nlohmann/json/issues/2171) +- How should strings be escaped? [\#2155](https://github.com/nlohmann/json/issues/2155) +- Adding a value to an existing json puts it at the beginning instead of the end [\#2149](https://github.com/nlohmann/json/issues/2149) +- The header file is big, can we use what we need. [\#2134](https://github.com/nlohmann/json/issues/2134) +- Changing the default format for unordered\_map \(or other set\) [\#2132](https://github.com/nlohmann/json/issues/2132) +- Getting size of deserialized bson document [\#2131](https://github.com/nlohmann/json/issues/2131) +- implicit conversion failure [\#2128](https://github.com/nlohmann/json/issues/2128) +- Error thrown when parsing in a subclass [\#2124](https://github.com/nlohmann/json/issues/2124) +- explicit conversion to string not considered for std::map keys in GCC8 [\#2096](https://github.com/nlohmann/json/issues/2096) +- Add support for JSONC [\#2061](https://github.com/nlohmann/json/issues/2061) +- Library provides template arg for string\_type but assumes std::string in some places [\#2059](https://github.com/nlohmann/json/issues/2059) +- incremental parsing with sax\_parser [\#2030](https://github.com/nlohmann/json/issues/2030) +- Question about flatten and unflatten [\#1989](https://github.com/nlohmann/json/issues/1989) +- CBOR parser doesn't skip tags [\#1968](https://github.com/nlohmann/json/issues/1968) +- Compilation failure using Clang on Windows [\#1898](https://github.com/nlohmann/json/issues/1898) +- Fail to build when including json.hpp as a system include [\#1818](https://github.com/nlohmann/json/issues/1818) +- Parsing string into json doesn't preserve the order correctly. [\#1817](https://github.com/nlohmann/json/issues/1817) +- \[C++17\] Allow std::optional to convert to nlohmann::json [\#1749](https://github.com/nlohmann/json/issues/1749) +- How can I save json object in file in order? [\#1717](https://github.com/nlohmann/json/issues/1717) +- Support for Comments [\#1513](https://github.com/nlohmann/json/issues/1513) +- clang compiler: error : unknown type name 'not' [\#1119](https://github.com/nlohmann/json/issues/1119) +- dump\(\) without alphabetical order [\#1106](https://github.com/nlohmann/json/issues/1106) +- operator T\(\) considered harmful [\#958](https://github.com/nlohmann/json/issues/958) +- Order of the elements in JSON object [\#952](https://github.com/nlohmann/json/issues/952) +- How to prevent alphabetical sorting of data? [\#727](https://github.com/nlohmann/json/issues/727) +- Why is an object ordering values by Alphabetical Order? [\#660](https://github.com/nlohmann/json/issues/660) +- Feature request: Comments [\#597](https://github.com/nlohmann/json/issues/597) +- Head Elements Sorting [\#543](https://github.com/nlohmann/json/issues/543) +- Automatic ordered JSON [\#424](https://github.com/nlohmann/json/issues/424) +- Support for comments. [\#376](https://github.com/nlohmann/json/issues/376) +- Optional comment support. [\#363](https://github.com/nlohmann/json/issues/363) +- Strip comments / Minify [\#294](https://github.com/nlohmann/json/issues/294) +- maintaining order of keys during iteration [\#106](https://github.com/nlohmann/json/issues/106) + +- Update documentation [\#2312](https://github.com/nlohmann/json/pull/2312) ([nlohmann](https://github.com/nlohmann)) +- Fix bug in CBOR tag handling [\#2308](https://github.com/nlohmann/json/pull/2308) ([nlohmann](https://github.com/nlohmann)) +- added inline to NLOHMANN\_DEFINE\_TYPE\_NON\_INTRUSIVE macro [\#2306](https://github.com/nlohmann/json/pull/2306) ([jwittbrodt](https://github.com/jwittbrodt)) +- fixes unused variable 'ex' for \#2304 [\#2305](https://github.com/nlohmann/json/pull/2305) ([AODQ](https://github.com/AODQ)) +- Cleanup [\#2303](https://github.com/nlohmann/json/pull/2303) ([nlohmann](https://github.com/nlohmann)) +- Add test with multiple translation units [\#2301](https://github.com/nlohmann/json/pull/2301) ([nlohmann](https://github.com/nlohmann)) +- Merge GitHub actions [\#2300](https://github.com/nlohmann/json/pull/2300) ([nlohmann](https://github.com/nlohmann)) +- Fix unused parameter [\#2299](https://github.com/nlohmann/json/pull/2299) ([nlohmann](https://github.com/nlohmann)) +- Add support for high-precision numbers in UBJSON encoding [\#2297](https://github.com/nlohmann/json/pull/2297) ([nlohmann](https://github.com/nlohmann)) +- fix eof for get\_binary and get\_string [\#2294](https://github.com/nlohmann/json/pull/2294) ([jprochazk](https://github.com/jprochazk)) +- Serialisation macros: increase upper bound on number of member variables [\#2287](https://github.com/nlohmann/json/pull/2287) ([pfeatherstone](https://github.com/pfeatherstone)) +- add inline specifier for detail::combine [\#2285](https://github.com/nlohmann/json/pull/2285) ([T0b1-iOS](https://github.com/T0b1-iOS)) +- Add static assertion for missing binary function in SAX interface [\#2282](https://github.com/nlohmann/json/pull/2282) ([nlohmann](https://github.com/nlohmann)) +- Add test for target\_include\_directories [\#2279](https://github.com/nlohmann/json/pull/2279) ([nlohmann](https://github.com/nlohmann)) +- Clean up maintainer Makefiles and fix some linter warnings [\#2274](https://github.com/nlohmann/json/pull/2274) ([nlohmann](https://github.com/nlohmann)) +- Add option to ignore CBOR tags [\#2273](https://github.com/nlohmann/json/pull/2273) ([nlohmann](https://github.com/nlohmann)) +- Hash function without allocation [\#2269](https://github.com/nlohmann/json/pull/2269) ([nlohmann](https://github.com/nlohmann)) +- Add ClangCL for MSVC [\#2268](https://github.com/nlohmann/json/pull/2268) ([t-b](https://github.com/t-b)) +- Makefile: Always use SED variable [\#2264](https://github.com/nlohmann/json/pull/2264) ([t-b](https://github.com/t-b)) +- Add Xcode 12 CI [\#2262](https://github.com/nlohmann/json/pull/2262) ([nlohmann](https://github.com/nlohmann)) +- Make library work with Clang on Windows [\#2259](https://github.com/nlohmann/json/pull/2259) ([nlohmann](https://github.com/nlohmann)) +- Add ordered\_json specialization with ordered object keys [\#2258](https://github.com/nlohmann/json/pull/2258) ([nlohmann](https://github.com/nlohmann)) +- Add pkg-config file [\#2253](https://github.com/nlohmann/json/pull/2253) ([ericonr](https://github.com/ericonr)) +- Fix regression from \#2181 [\#2251](https://github.com/nlohmann/json/pull/2251) ([nlohmann](https://github.com/nlohmann)) +- Tag binary values in cbor if set [\#2244](https://github.com/nlohmann/json/pull/2244) ([matthewbauer](https://github.com/matthewbauer)) +- Make assert configurable via JSON\_ASSERT [\#2242](https://github.com/nlohmann/json/pull/2242) ([nlohmann](https://github.com/nlohmann)) +- Add specialization of get\_to [\#2233](https://github.com/nlohmann/json/pull/2233) ([nlohmann](https://github.com/nlohmann)) +- Refine documentation of error\_handler parameter [\#2232](https://github.com/nlohmann/json/pull/2232) ([nlohmann](https://github.com/nlohmann)) +- Simplify conversion from/to custom types [\#2225](https://github.com/nlohmann/json/pull/2225) ([nlohmann](https://github.com/nlohmann)) +- Remove unused typedefs [\#2224](https://github.com/nlohmann/json/pull/2224) ([nlohmann](https://github.com/nlohmann)) +- Enable CMake policy CMP0077 [\#2222](https://github.com/nlohmann/json/pull/2222) ([alexreinking](https://github.com/alexreinking)) +- Add option to ignore comments in parse/accept functions [\#2212](https://github.com/nlohmann/json/pull/2212) ([nlohmann](https://github.com/nlohmann)) +- Fix Clang-Tidy warnings [\#2211](https://github.com/nlohmann/json/pull/2211) ([nlohmann](https://github.com/nlohmann)) +- Simple ordered\_json that works on all supported compilers [\#2206](https://github.com/nlohmann/json/pull/2206) ([gatopeich](https://github.com/gatopeich)) +- Use unsigned indizies for array index in json pointer [\#2203](https://github.com/nlohmann/json/pull/2203) ([t-b](https://github.com/t-b)) +- Add option to not rely on Internet connectivity during test stage [\#2202](https://github.com/nlohmann/json/pull/2202) ([nlohmann](https://github.com/nlohmann)) +- Serialize floating-point numbers with 32 bit when possible \(MessagePack\) [\#2201](https://github.com/nlohmann/json/pull/2201) ([nlohmann](https://github.com/nlohmann)) +- Fix consistency in function `int_to_string()` [\#2193](https://github.com/nlohmann/json/pull/2193) ([dota17](https://github.com/dota17)) +- Fix issue\#1275 [\#2181](https://github.com/nlohmann/json/pull/2181) ([dota17](https://github.com/dota17)) +- C++20 support by removing swap specialization [\#2176](https://github.com/nlohmann/json/pull/2176) ([gracicot](https://github.com/gracicot)) +- Feat/explicit conversion operator [\#1559](https://github.com/nlohmann/json/pull/1559) ([theodelrieu](https://github.com/theodelrieu)) + +## [v3.8.0](https://github.com/nlohmann/json/releases/tag/v3.8.0) (2020-06-14) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.3...v3.8.0) + +- sorry delete this issue, i'm stupid [\#2187](https://github.com/nlohmann/json/issues/2187) +- Append to a std::nlohmann::json type [\#2186](https://github.com/nlohmann/json/issues/2186) +- Some troubles to compile the last revision [\#2177](https://github.com/nlohmann/json/issues/2177) +- ​\#​ Top level CMakeLists.txt​ +​project​\(FOO\) +... +​option​\(FOO\_USE\_EXTERNAL\_JSON ​"Use an external JSON library"​ ​OFF​\) +... +​add\_subdirectory​\(thirdparty\) +... +​add\_library​\(foo ...\) +... +​\#​ Note that the namespaced target will always be available regardless of the​ +​\#​ import method​ +​target\_link\_libraries​\(foo ​PRIVATE​ nlohmann\_json::nlohmann\_json\) [\#2170](https://github.com/nlohmann/json/issues/2170) +- https://www.github.com/nlohmann/json/tree/develop/include%2Fnlohmann%2Fjson\_fwd.hpp [\#2169](https://github.com/nlohmann/json/issues/2169) +- templated from\_json of non primitive types causes gcc error [\#2168](https://github.com/nlohmann/json/issues/2168) +- few warnings/errors in copy assignment [\#2167](https://github.com/nlohmann/json/issues/2167) +- Different output when upgrading from clang 9 to clang 10 [\#2166](https://github.com/nlohmann/json/issues/2166) +- Cannot build with VS 2019 / C++17 [\#2163](https://github.com/nlohmann/json/issues/2163) +- Q: When I received an illegal string,How the program knows? [\#2162](https://github.com/nlohmann/json/issues/2162) +- Problem while reading a json file [\#2161](https://github.com/nlohmann/json/issues/2161) +- converting std::chrono::system\_clock::time\_point to json. [\#2159](https://github.com/nlohmann/json/issues/2159) +- how to parse vector\ format [\#2157](https://github.com/nlohmann/json/issues/2157) +- nlohmann::json and =nullptr [\#2156](https://github.com/nlohmann/json/issues/2156) +- test-cbor fails [\#2154](https://github.com/nlohmann/json/issues/2154) +- Accessing array inside array syntax? [\#2151](https://github.com/nlohmann/json/issues/2151) +- Best way to catch errors when querying json [\#2150](https://github.com/nlohmann/json/issues/2150) +- JSON Data Mapping Key-Value from other Key-Value [\#2148](https://github.com/nlohmann/json/issues/2148) +- Conflicts with std \ compiling with GCC 10 [\#2146](https://github.com/nlohmann/json/issues/2146) +- Incorrect CMake FetchContent example [\#2142](https://github.com/nlohmann/json/issues/2142) +- Help for a Beginner? [\#2141](https://github.com/nlohmann/json/issues/2141) +- Read Json from File [\#2139](https://github.com/nlohmann/json/issues/2139) +- How to feed a predefined integer value into json string [\#2138](https://github.com/nlohmann/json/issues/2138) +- getting json array inside json object [\#2135](https://github.com/nlohmann/json/issues/2135) +- Add .contains example to doc [\#2133](https://github.com/nlohmann/json/issues/2133) +- Is it safe to return string.c\_str\(\) received from get\(\)? [\#2130](https://github.com/nlohmann/json/issues/2130) +- GCC 10: Compilation error when including any before including json header in C++17 mode [\#2129](https://github.com/nlohmann/json/issues/2129) +- Intersection of two json files [\#2127](https://github.com/nlohmann/json/issues/2127) +- App crashes when dump method called for non ascii chars. [\#2126](https://github.com/nlohmann/json/issues/2126) +- iterator based erase method [\#2122](https://github.com/nlohmann/json/issues/2122) +- quick and convenient api to get/set nested json values [\#2120](https://github.com/nlohmann/json/issues/2120) +- assigning nullptr to std::string [\#2118](https://github.com/nlohmann/json/issues/2118) +- usless\_cast warnings with gcc 9.3 and 10.1 \(C++17\) [\#2114](https://github.com/nlohmann/json/issues/2114) +- clang 10 warning [\#2113](https://github.com/nlohmann/json/issues/2113) +- Possible incorrect \_MSC\_VER reference [\#2112](https://github.com/nlohmann/json/issues/2112) +- warning under gcc 10.1 [\#2110](https://github.com/nlohmann/json/issues/2110) +- Wdeprecated-declarations from GCC v10.1.0 [\#2109](https://github.com/nlohmann/json/issues/2109) +- Global std::vector from json [\#2108](https://github.com/nlohmann/json/issues/2108) +- heap-buffer-overflow when using nlohmann/json, ASAN, and gtest [\#2107](https://github.com/nlohmann/json/issues/2107) +- exception 0x770DC5AF when i read an special char in json file [\#2106](https://github.com/nlohmann/json/issues/2106) +- json::parse\(\) fails to parse a dump\(2,' '\) output, yet does successfully parse dump\(\) [\#2105](https://github.com/nlohmann/json/issues/2105) +- run test-udt error in MSVC 19.16.27034.0 [\#2103](https://github.com/nlohmann/json/issues/2103) +- Unable to dump to stringstream [\#2102](https://github.com/nlohmann/json/issues/2102) +- Can't ad an object in another objet [\#2101](https://github.com/nlohmann/json/issues/2101) +- Implicit conversion causes "cannot use operator\[\] with a string argument with string" [\#2098](https://github.com/nlohmann/json/issues/2098) +- C++20: char8\_t [\#2097](https://github.com/nlohmann/json/issues/2097) +- Compilation issues when included in project [\#2094](https://github.com/nlohmann/json/issues/2094) +- string value with null character causes infinite loop [\#2093](https://github.com/nlohmann/json/issues/2093) +- corrupted size vs. prev\_size \(aborted\) [\#2092](https://github.com/nlohmann/json/issues/2092) +- Get string field content without return std::string copy [\#2091](https://github.com/nlohmann/json/issues/2091) +- JSON Comments \(JSON 5\) [\#2090](https://github.com/nlohmann/json/issues/2090) +- Remove \#include \ [\#2089](https://github.com/nlohmann/json/issues/2089) +- JSON library as a git submodule [\#2088](https://github.com/nlohmann/json/issues/2088) +- Apple Clang 11.0.3 on MacOS Catalina 10.15.4 not compiling [\#2087](https://github.com/nlohmann/json/issues/2087) +- Value function return empty object even if it exist [\#2086](https://github.com/nlohmann/json/issues/2086) +- Cannot debug but Run works [\#2085](https://github.com/nlohmann/json/issues/2085) +- Question about serialization. [\#2084](https://github.com/nlohmann/json/issues/2084) +- How to include in an external project [\#2083](https://github.com/nlohmann/json/issues/2083) +- Missing tests for binary values [\#2082](https://github.com/nlohmann/json/issues/2082) +- How to override default string serialization? [\#2079](https://github.com/nlohmann/json/issues/2079) +- Can't have a json type as a property in an arbitrary type [\#2078](https://github.com/nlohmann/json/issues/2078) +- New release? [\#2075](https://github.com/nlohmann/json/issues/2075) +- CMake FetchContent \> Updating the documentation? [\#2073](https://github.com/nlohmann/json/issues/2073) +- How to convert STL Vector \(of user defined type\) to Json [\#2072](https://github.com/nlohmann/json/issues/2072) +- how to make an array of objects [\#2070](https://github.com/nlohmann/json/issues/2070) +- ‘\_\_int64’ was not declared [\#2068](https://github.com/nlohmann/json/issues/2068) +- \[json.exception.type\_error.317\] cannot serialize binary data to text JSON [\#2067](https://github.com/nlohmann/json/issues/2067) +- Unexpected end of input; expected '\[', '{', or a literal [\#2066](https://github.com/nlohmann/json/issues/2066) +- Json structure can be nested? [\#2065](https://github.com/nlohmann/json/issues/2065) +- Bug: returning reference to local temporary object [\#2064](https://github.com/nlohmann/json/issues/2064) +- Allow to use non strict parsing [\#2063](https://github.com/nlohmann/json/issues/2063) +- Crashing on json::at [\#2062](https://github.com/nlohmann/json/issues/2062) +- How to convert a const std::vector\ message to a json, to be able to parse it and extract information from it? Can you point to any examples? [\#2058](https://github.com/nlohmann/json/issues/2058) +- Nice library [\#2057](https://github.com/nlohmann/json/issues/2057) +- json.hpp:15372:22: error: expected unqualified-id if \(not std::isfinite\(x\)\): Started getting this bug after updating my XCode [\#2056](https://github.com/nlohmann/json/issues/2056) +- Confused as how I can extract the values from the JSON object. [\#2055](https://github.com/nlohmann/json/issues/2055) +- Warnings with GCC 10 [\#2052](https://github.com/nlohmann/json/issues/2052) +- Warnings with Clang 10 [\#2049](https://github.com/nlohmann/json/issues/2049) +- Update doctest [\#2048](https://github.com/nlohmann/json/issues/2048) +- Unclear error message: "cannot use operator\[\] with a string argument with array" [\#2047](https://github.com/nlohmann/json/issues/2047) +- Serializing std::variant\\> [\#2045](https://github.com/nlohmann/json/issues/2045) +- Crash when parse big jsonfile [\#2042](https://github.com/nlohmann/json/issues/2042) +- How to check if a key exists without silently generating null objects on the path [\#2041](https://github.com/nlohmann/json/issues/2041) +- Crash when traversing over items\(\) of temporary json objects [\#2040](https://github.com/nlohmann/json/issues/2040) +- How to parse multiple line value ? [\#2039](https://github.com/nlohmann/json/issues/2039) +- SAX API uses unsigned std::size\_t but -1 if element size is not known; [\#2037](https://github.com/nlohmann/json/issues/2037) +- How to parse big decimal data [\#2036](https://github.com/nlohmann/json/issues/2036) +- how use template \ struct adl\_serializer [\#2035](https://github.com/nlohmann/json/issues/2035) +- auto iterator returned by find to handle value depending if is string or numeric. [\#2032](https://github.com/nlohmann/json/issues/2032) +- pass find returned iterator to numeric variable. [\#2031](https://github.com/nlohmann/json/issues/2031) +- Parse error on valid json file [\#2029](https://github.com/nlohmann/json/issues/2029) +- Is here any elegant way to combine serialization and deserialization code? [\#2028](https://github.com/nlohmann/json/issues/2028) +- Notes about dump function [\#2027](https://github.com/nlohmann/json/issues/2027) +- Different JSON printouts for empty dictionary on Linux and Mac. [\#2026](https://github.com/nlohmann/json/issues/2026) +- easier way to get exception reason out of json\_sax\_dom\_callback\_parser without exceptions [\#2024](https://github.com/nlohmann/json/issues/2024) +- Using fifo\_map with base class and derived class [\#2023](https://github.com/nlohmann/json/issues/2023) +- Error reading JSON File [\#2022](https://github.com/nlohmann/json/issues/2022) +- Parse causing crash on android. Cannot catch. [\#2021](https://github.com/nlohmann/json/issues/2021) +- Extra backslashes in nested json [\#2020](https://github.com/nlohmann/json/issues/2020) +- How to create patch for merge\_patch input ? [\#2018](https://github.com/nlohmann/json/issues/2018) +- CppUTest/include/CppUTestExt/MockSupport.h:40: error: default argument for ‘MockFailureReporter\* failureReporterForThisCall’ has type ‘void\*’ [\#2017](https://github.com/nlohmann/json/issues/2017) +- including another file [\#2016](https://github.com/nlohmann/json/issues/2016) +- GNU PREREQ Error with gcc 9.3.0 [\#2015](https://github.com/nlohmann/json/issues/2015) +- Parse error: json.exception.parse\_error.101 - invalid string: ill-formed UTF-8 byte [\#2014](https://github.com/nlohmann/json/issues/2014) +- Add more flexibility to basic\_json's ObjectType \(and ArrayType\) [\#2013](https://github.com/nlohmann/json/issues/2013) +- afl persistent mode [\#2012](https://github.com/nlohmann/json/issues/2012) +- Compiler Errors under VS2019 in Appveyor CI [\#2009](https://github.com/nlohmann/json/issues/2009) +- Another compilation failure with Visual Studio [\#2007](https://github.com/nlohmann/json/issues/2007) +- Implicit cast to std::string broken again with VS2019 16.5.0 [\#2006](https://github.com/nlohmann/json/issues/2006) +- error: no matching member function for call to 'AddRaw' [\#2005](https://github.com/nlohmann/json/issues/2005) +- When I re-create an object again after the network request, an error is reported [\#2003](https://github.com/nlohmann/json/issues/2003) +- How to merge \(and not replace\) different Json::Value objects in jsoncpp [\#2001](https://github.com/nlohmann/json/issues/2001) +- scalar transforms to list [\#2000](https://github.com/nlohmann/json/issues/2000) +- Dump JSON containing multibyte characters [\#1999](https://github.com/nlohmann/json/issues/1999) +- Build error when modify value [\#1998](https://github.com/nlohmann/json/issues/1998) +- How do i include a vector of pointers in my json? [\#1997](https://github.com/nlohmann/json/issues/1997) +- Compiler error wrt incomplete types changed in gcc8.3.0-26 [\#1996](https://github.com/nlohmann/json/issues/1996) +- NaN-like comparison behavior of discarded is inconvenient [\#1988](https://github.com/nlohmann/json/issues/1988) +- Maintaining JSON package in my CMake [\#1987](https://github.com/nlohmann/json/issues/1987) +- reading int number and string number [\#1986](https://github.com/nlohmann/json/issues/1986) +- Build error: keyword is hidden by macro definition! [\#1985](https://github.com/nlohmann/json/issues/1985) +- JSON patch diff for op=add formation is not as per standard \(RFC 6902\) [\#1983](https://github.com/nlohmann/json/issues/1983) +- json\_pointer.contains\(\) exception is incorrectly raised [\#1982](https://github.com/nlohmann/json/issues/1982) +- Error with non existing key [\#1981](https://github.com/nlohmann/json/issues/1981) +- Closed [\#1978](https://github.com/nlohmann/json/issues/1978) +- Where is the library built and what is the name? [\#1977](https://github.com/nlohmann/json/issues/1977) +- The cmake\_import example does not build [\#1976](https://github.com/nlohmann/json/issues/1976) +- Dumping core when reading invalid file [\#1975](https://github.com/nlohmann/json/issues/1975) +- Abort in dump\(\) method [\#1973](https://github.com/nlohmann/json/issues/1973) +- Unclear docs regarding parser\_callback\_t callbacks [\#1972](https://github.com/nlohmann/json/issues/1972) +- Possible memory leak on push\_back [\#1971](https://github.com/nlohmann/json/issues/1971) +- Is it possible to get a safe mutable reference/pointer to internal variant used in nlohmann json? [\#1970](https://github.com/nlohmann/json/issues/1970) +- Getting a flatten json to map\ [\#1957](https://github.com/nlohmann/json/issues/1957) +- forced type conversion or lexical cast without exception. [\#1955](https://github.com/nlohmann/json/issues/1955) +- Add json\_view type support to avoid excessive copying [\#1954](https://github.com/nlohmann/json/issues/1954) +- Adding "examples" section for real-life usages [\#1953](https://github.com/nlohmann/json/issues/1953) +- Add nlohmann::json::key\_type [\#1951](https://github.com/nlohmann/json/issues/1951) +- cannot use operator\[\] with a string argument with string [\#1949](https://github.com/nlohmann/json/issues/1949) +- std::ifstream \>\> json error [\#1948](https://github.com/nlohmann/json/issues/1948) +- Cannot update json data in an iterator? [\#1947](https://github.com/nlohmann/json/issues/1947) +- How can i build this library in VS 2017? [\#1943](https://github.com/nlohmann/json/issues/1943) +- json\_pointer.contains\(\) exceptions when path not found [\#1942](https://github.com/nlohmann/json/issues/1942) +- Nested objects serialize/deserialize [\#1941](https://github.com/nlohmann/json/issues/1941) +- Compile warning on architectures that are not x86 [\#1939](https://github.com/nlohmann/json/issues/1939) +- Version of nlohmann-json-dev in debian packages [\#1938](https://github.com/nlohmann/json/issues/1938) +- Create a json object for every cycle [\#1937](https://github.com/nlohmann/json/issues/1937) +- How to get the object name? [\#1936](https://github.com/nlohmann/json/issues/1936) +- Reserve and resize function for basic json [\#1935](https://github.com/nlohmann/json/issues/1935) +- How to use json parse in tsl::ordread\_map? [\#1934](https://github.com/nlohmann/json/issues/1934) +- C++14 support is not enabled with msvc2015 [\#1932](https://github.com/nlohmann/json/issues/1932) +- Need help with to\_json for derived class, keep getting "cannot use operator" [\#1931](https://github.com/nlohmann/json/issues/1931) +- How to handle std::vector\ [\#1930](https://github.com/nlohmann/json/issues/1930) +- Heap corruption issue [\#1929](https://github.com/nlohmann/json/issues/1929) +- Add `std::wistream` support. [\#1928](https://github.com/nlohmann/json/issues/1928) +- This i can write and read any file thanks [\#1927](https://github.com/nlohmann/json/issues/1927) +- How can I get this simple example working? [\#1926](https://github.com/nlohmann/json/issues/1926) +- emplace\_back does not seems to work with the int 0 [\#1925](https://github.com/nlohmann/json/issues/1925) +- Why nlohmann does not release memory [\#1924](https://github.com/nlohmann/json/issues/1924) +- Is it possible to have template `json::parse` with `noexcept` specifier? [\#1922](https://github.com/nlohmann/json/issues/1922) +- JSON to wstring? [\#1921](https://github.com/nlohmann/json/issues/1921) +- GCC 10 tests build failure [\#1920](https://github.com/nlohmann/json/issues/1920) +- Size of binary json representations [\#1919](https://github.com/nlohmann/json/issues/1919) +- Accessing strings \(for example in keys or values\) without having the lib create a copy of it. [\#1916](https://github.com/nlohmann/json/issues/1916) +- operator== documentation should show how to apply custom comparison function [\#1915](https://github.com/nlohmann/json/issues/1915) +- char8\_t and std::u8string support [\#1914](https://github.com/nlohmann/json/issues/1914) +- std::is\_pod is deprecated in C++20 [\#1913](https://github.com/nlohmann/json/issues/1913) +- Incomplete types reported by \(experimental\) GCC10 [\#1912](https://github.com/nlohmann/json/issues/1912) +- Compile warnings on MSVC 14.2 [\#1911](https://github.com/nlohmann/json/issues/1911) +- How to parse json file with type composition of std::optional and std::variant [\#1910](https://github.com/nlohmann/json/issues/1910) +- why root\_schema be implemented as unique\_ptr in json-validator.cpp,could I use it as shared\_ptr? [\#1908](https://github.com/nlohmann/json/issues/1908) +- compile error in gcc-6.3.0 [\#1906](https://github.com/nlohmann/json/issues/1906) +- Scalar constexpr is odr-used when used as json initializer [\#1905](https://github.com/nlohmann/json/issues/1905) +- install Slack app [\#1904](https://github.com/nlohmann/json/issues/1904) +- typo in a comment [\#1903](https://github.com/nlohmann/json/issues/1903) +- Watch JSON variables in Debug [\#1902](https://github.com/nlohmann/json/issues/1902) +- does Json sdk cares about dfc dfd utf8 issue? [\#1901](https://github.com/nlohmann/json/issues/1901) +- Allow multiple line string value in JSON [\#1897](https://github.com/nlohmann/json/issues/1897) +- Writing map to json file [\#1896](https://github.com/nlohmann/json/issues/1896) +- Small documentation mistake [\#1895](https://github.com/nlohmann/json/issues/1895) +- why static function `parse` cann't find in visual studio 2019 [\#1894](https://github.com/nlohmann/json/issues/1894) +- Best way to handle json files with missing key value pairs. [\#1893](https://github.com/nlohmann/json/issues/1893) +- accessing json object as multimap [\#1892](https://github.com/nlohmann/json/issues/1892) +- What is the best way to parse vec3s into glm::vec3 [\#1891](https://github.com/nlohmann/json/issues/1891) +- Get array of items without using vector [\#1890](https://github.com/nlohmann/json/issues/1890) +- Build errors \(clang 11.0.0\) on macOS 10.15.2 [\#1889](https://github.com/nlohmann/json/issues/1889) +- Multiple arrays to vectors help [\#1888](https://github.com/nlohmann/json/issues/1888) +- json::parse\(begin, end\) parse error on first character using uchar\* [\#1887](https://github.com/nlohmann/json/issues/1887) +- issue in free\(\) [\#1886](https://github.com/nlohmann/json/issues/1886) +- is\_number\_unsigned\(\) returns false for positive integers \(int or 0 or 1 literals\) [\#1885](https://github.com/nlohmann/json/issues/1885) +- MSVC build failure with /Zc:\_\_cplusplus and C++17 [\#1883](https://github.com/nlohmann/json/issues/1883) +- RFC 6901 op:replace & arrays [\#1882](https://github.com/nlohmann/json/issues/1882) +- Problem with serialization of my custom template doubly-linked list [\#1881](https://github.com/nlohmann/json/issues/1881) +- is\_array\(\) is True, but raise 'cannot use operator\[\] for object iterators' [\#1880](https://github.com/nlohmann/json/issues/1880) +- Serialize dynamic array [\#1879](https://github.com/nlohmann/json/issues/1879) +- Serialization of struct object. [\#1877](https://github.com/nlohmann/json/issues/1877) +- warning:c4503 [\#1875](https://github.com/nlohmann/json/issues/1875) +- Why are flattened empty objects/arrays not representable? [\#1874](https://github.com/nlohmann/json/issues/1874) +- Container Overflow \(ASAN\) when using operator \>\> on an ifs [\#1873](https://github.com/nlohmann/json/issues/1873) +- Sub-array to vector or map object? [\#1870](https://github.com/nlohmann/json/issues/1870) +- WIP: QT \(cute\) type supports [\#1869](https://github.com/nlohmann/json/issues/1869) +- Compiler flags to disable features and shrink code size [\#1868](https://github.com/nlohmann/json/issues/1868) +- null strings [\#1867](https://github.com/nlohmann/json/issues/1867) +- Struct with array of struct and \_\_attribute\_\_\(\(packed\)\) [\#1866](https://github.com/nlohmann/json/issues/1866) +- Best way to extract numbers in the string? [\#1865](https://github.com/nlohmann/json/issues/1865) +- Displaying \\?\Volume{guid} from string to json giving error [\#1864](https://github.com/nlohmann/json/issues/1864) +- not working when compiling as x86 [\#1863](https://github.com/nlohmann/json/issues/1863) +- Skipping evaluation of log line expressions with a macro, is it possible? [\#1862](https://github.com/nlohmann/json/issues/1862) +- Suppress warnings [\#1861](https://github.com/nlohmann/json/issues/1861) +- conflit with g++ compile option -mwindows [\#1860](https://github.com/nlohmann/json/issues/1860) +- How to serialize nested classes to semi-flat JSON object? [\#1859](https://github.com/nlohmann/json/issues/1859) +- Memory Requirement for large json file [\#1858](https://github.com/nlohmann/json/issues/1858) +- Query a binary format \(BSON, CBOR, MessagePack, UBJSON\) [\#1856](https://github.com/nlohmann/json/issues/1856) +- Documentation on operator\[\] behavior with missing keys [\#1855](https://github.com/nlohmann/json/issues/1855) +- Problem in converting string into JSON; Can't parse successfully. [\#1854](https://github.com/nlohmann/json/issues/1854) +- json.at\_or\_default\(key, defaultval\) [\#1852](https://github.com/nlohmann/json/issues/1852) +- please improve the enum conversion documentation \(my example gist provided\) [\#1851](https://github.com/nlohmann/json/issues/1851) +- Default value returned on ValueType nlohmann::basic\_json::value \(const typename object\_t::key\_type& key, const ValueType& default\_value\) [\#1850](https://github.com/nlohmann/json/issues/1850) +- Accounting for arbitrary precision numerical literals [\#1849](https://github.com/nlohmann/json/issues/1849) +- While trying to make a simple array, I get a nested array instead [\#1848](https://github.com/nlohmann/json/issues/1848) +- How to reuse the parser and serializer intermediate storage? [\#1847](https://github.com/nlohmann/json/issues/1847) +- Too much content in json.hpp leads to slow compilation [\#1845](https://github.com/nlohmann/json/issues/1845) +- Cannot read some data in json file [\#1843](https://github.com/nlohmann/json/issues/1843) +- Precompiled JSON library? [\#1842](https://github.com/nlohmann/json/issues/1842) +- Please change assert into throw\(maybe\) in line 17946 [\#1841](https://github.com/nlohmann/json/issues/1841) +- JSON for modern C++ ECCN information [\#1840](https://github.com/nlohmann/json/issues/1840) +- CI: reduce build time for Travis valgrind [\#1836](https://github.com/nlohmann/json/issues/1836) +- How do I traverse a json object and add new elements into the hierarchy [\#1834](https://github.com/nlohmann/json/issues/1834) +- Invalid UTF-8 byte at index 1: 0x65 [\#1831](https://github.com/nlohmann/json/issues/1831) +- Serialize big data in json [\#1828](https://github.com/nlohmann/json/issues/1828) +- Backslash '\' in value causes exception [\#1827](https://github.com/nlohmann/json/issues/1827) +- from\_json for non default constructible class with dependency injection [\#1819](https://github.com/nlohmann/json/issues/1819) +- Semi-frequent timeouts in `test-unicode_all` with 3.6.1 \(aarch64\) [\#1816](https://github.com/nlohmann/json/issues/1816) +- input\_adapter not user extensible [\#1813](https://github.com/nlohmann/json/issues/1813) +- crash at json::destroy on android [\#1812](https://github.com/nlohmann/json/issues/1812) +- Logs are repeating while cmake [\#1809](https://github.com/nlohmann/json/issues/1809) +- Add a the possibility to add dynamic json objects [\#1795](https://github.com/nlohmann/json/issues/1795) +- Unnecessary test data file in the release [\#1790](https://github.com/nlohmann/json/issues/1790) +- Add support for parse stack limiting [\#1788](https://github.com/nlohmann/json/issues/1788) +- GCC -Wuseless-cast warnings [\#1777](https://github.com/nlohmann/json/issues/1777) +- compilation issue with NVCC 9.0 [\#1773](https://github.com/nlohmann/json/issues/1773) +- Unexpected behavior with fifo\_map json when copy and append [\#1763](https://github.com/nlohmann/json/issues/1763) +- Parse error [\#1761](https://github.com/nlohmann/json/issues/1761) +- Assignment \(using value\(\)\) to nonexistent element behaves differently on Xcode 8 vs Xcode 10 [\#1758](https://github.com/nlohmann/json/issues/1758) +- Readme out of date [\#1756](https://github.com/nlohmann/json/issues/1756) +- cmake\_\* tests don't use the build system's compiler [\#1747](https://github.com/nlohmann/json/issues/1747) +- Static assertions for template type properties required [\#1729](https://github.com/nlohmann/json/issues/1729) +- Use float and possibly half in json::to\_cbor [\#1719](https://github.com/nlohmann/json/issues/1719) +- json::from\_cbor does not respect allow\_exceptions = false when input is string literal [\#1715](https://github.com/nlohmann/json/issues/1715) +- /Zc:\_\_cplusplus leads to C2416 [\#1695](https://github.com/nlohmann/json/issues/1695) +- `unflatten` vs objects with number-ish keys [\#1575](https://github.com/nlohmann/json/issues/1575) +- A "thinner" source code tar as part of release? [\#1572](https://github.com/nlohmann/json/issues/1572) +- Repository is almost 450MB [\#1497](https://github.com/nlohmann/json/issues/1497) +- Substantial performance penalty caused by polymorphic input adapter [\#1457](https://github.com/nlohmann/json/issues/1457) +- Move tests to a separate repo [\#1235](https://github.com/nlohmann/json/issues/1235) +- reduce repos size [\#1185](https://github.com/nlohmann/json/issues/1185) +- CMakeLists.txt in release zips? [\#1184](https://github.com/nlohmann/json/issues/1184) +- Minimal branch? [\#1066](https://github.com/nlohmann/json/issues/1066) +- Move test blobs to a submodule? [\#732](https://github.com/nlohmann/json/issues/732) +- \[Question\] When using this as git submodule, will it clone the whole thing include test data and benchmark? [\#620](https://github.com/nlohmann/json/issues/620) +- Need to improve ignores.. [\#567](https://github.com/nlohmann/json/issues/567) +- Minimal repository \(current size very large\) [\#556](https://github.com/nlohmann/json/issues/556) +- For a header-only library you have to clone 214MB [\#482](https://github.com/nlohmann/json/issues/482) +- 17 MB / 90 MB repo size!? [\#96](https://github.com/nlohmann/json/issues/96) + +- Improve parse\_ubjson\_fuzzer [\#2182](https://github.com/nlohmann/json/pull/2182) ([tanuj208](https://github.com/tanuj208)) +- Add input adapter tests [\#2178](https://github.com/nlohmann/json/pull/2178) ([nlohmann](https://github.com/nlohmann)) +- Fix warnings [\#2174](https://github.com/nlohmann/json/pull/2174) ([nlohmann](https://github.com/nlohmann)) +- Fix PR\#1006 [\#2158](https://github.com/nlohmann/json/pull/2158) ([dota17](https://github.com/dota17)) +- Fix issue\#1972 [\#2153](https://github.com/nlohmann/json/pull/2153) ([dota17](https://github.com/dota17)) +- Update URLs to HTTPS [\#2152](https://github.com/nlohmann/json/pull/2152) ([TotalCaesar659](https://github.com/TotalCaesar659)) +- Fix Issue\#1813: user defined input adapters [\#2145](https://github.com/nlohmann/json/pull/2145) ([FrancoisChabot](https://github.com/FrancoisChabot)) +- Fix issue\#1939: Cast character to unsigned for comparison [\#2144](https://github.com/nlohmann/json/pull/2144) ([XyFreak](https://github.com/XyFreak)) +- Fix issue\#2142: readme: fix typo in CMake FetchContent example [\#2143](https://github.com/nlohmann/json/pull/2143) ([quentin-dev](https://github.com/quentin-dev)) +- Respect allow\_exceptions=false for binary formats [\#2140](https://github.com/nlohmann/json/pull/2140) ([nlohmann](https://github.com/nlohmann)) +- Fix issue 2112 [\#2137](https://github.com/nlohmann/json/pull/2137) ([dota17](https://github.com/dota17)) +- Add bleeding edge GCC to CI [\#2136](https://github.com/nlohmann/json/pull/2136) ([aokellermann](https://github.com/aokellermann)) +- Clean up implementation of binary type [\#2125](https://github.com/nlohmann/json/pull/2125) ([nlohmann](https://github.com/nlohmann)) +- Fixed a compilation error in MSVC [\#2121](https://github.com/nlohmann/json/pull/2121) ([gistrec](https://github.com/gistrec)) +- Overwork CI [\#2119](https://github.com/nlohmann/json/pull/2119) ([nlohmann](https://github.com/nlohmann)) +- Fix warnings from Clang 10 and GCC 9 [\#2116](https://github.com/nlohmann/json/pull/2116) ([nlohmann](https://github.com/nlohmann)) +- Do not include \ when using C++17 [\#2115](https://github.com/nlohmann/json/pull/2115) ([nlohmann](https://github.com/nlohmann)) +- Fix issue\#2086: disallow json::value\_t type parameter in value\(\) [\#2104](https://github.com/nlohmann/json/pull/2104) ([dota17](https://github.com/dota17)) +- Fix Coveralls integration [\#2100](https://github.com/nlohmann/json/pull/2100) ([nlohmann](https://github.com/nlohmann)) +- Add tests for binary values [\#2099](https://github.com/nlohmann/json/pull/2099) ([nlohmann](https://github.com/nlohmann)) +- Use external test data [\#2081](https://github.com/nlohmann/json/pull/2081) ([nlohmann](https://github.com/nlohmann)) +- Remove Doozer CI [\#2080](https://github.com/nlohmann/json/pull/2080) ([nlohmann](https://github.com/nlohmann)) +- Fix README.md. Missing ``` [\#2077](https://github.com/nlohmann/json/pull/2077) ([ArthurSonzogni](https://github.com/ArthurSonzogni)) +- Fix error message about invalid surrogate pairs [\#2076](https://github.com/nlohmann/json/pull/2076) ([rmisev](https://github.com/rmisev)) +- Add CMake fetchcontent documentation and tests [\#2074](https://github.com/nlohmann/json/pull/2074) ([ArthurSonzogni](https://github.com/ArthurSonzogni)) +- Properly pass serialize\_binary to dump function [\#2071](https://github.com/nlohmann/json/pull/2071) ([nlohmann](https://github.com/nlohmann)) +- Fix returning reference to local temporary object [\#2069](https://github.com/nlohmann/json/pull/2069) ([nlohmann](https://github.com/nlohmann)) +- updated wandbox link [\#2060](https://github.com/nlohmann/json/pull/2060) ([alexandermyasnikov](https://github.com/alexandermyasnikov)) +- Fix bug in diff function [\#2054](https://github.com/nlohmann/json/pull/2054) ([nlohmann](https://github.com/nlohmann)) +- Fix GCC compiler warnings [\#2053](https://github.com/nlohmann/json/pull/2053) ([nlohmann](https://github.com/nlohmann)) +- Fix Clang compiler warnings [\#2051](https://github.com/nlohmann/json/pull/2051) ([nlohmann](https://github.com/nlohmann)) +- Update doctest to 2.3.7 [\#2050](https://github.com/nlohmann/json/pull/2050) ([nlohmann](https://github.com/nlohmann)) +- Fix issue\#1719 [\#2044](https://github.com/nlohmann/json/pull/2044) ([dota17](https://github.com/dota17)) +- Add missing testcase about NaN in unit-constructor1.cpp [\#2043](https://github.com/nlohmann/json/pull/2043) ([dota17](https://github.com/dota17)) +- Templatize basic\_json constructor from json\_ref [\#2034](https://github.com/nlohmann/json/pull/2034) ([ArtemSarmini](https://github.com/ArtemSarmini)) +- Replace deprecated std::is\_pod [\#2033](https://github.com/nlohmann/json/pull/2033) ([nlohmann](https://github.com/nlohmann)) +- Fixes \#1971 \(memory leak in basic\_json::push\_back\) [\#2025](https://github.com/nlohmann/json/pull/2025) ([ArtemSarmini](https://github.com/ArtemSarmini)) +- fix \#1982:json\_pointer.contains\(\) exception is incorrectly raised [\#2019](https://github.com/nlohmann/json/pull/2019) ([dota17](https://github.com/dota17)) +- Update LICENSE.MIT [\#2010](https://github.com/nlohmann/json/pull/2010) ([magamig](https://github.com/magamig)) +- PR for \#2006 to test in AppVeyor. [\#2008](https://github.com/nlohmann/json/pull/2008) ([garethsb](https://github.com/garethsb)) +- Added wsjcpp.yml [\#2004](https://github.com/nlohmann/json/pull/2004) ([sea-kg](https://github.com/sea-kg)) +- fix error 'setw' is not a member of 'std' in Wandbox example [\#2002](https://github.com/nlohmann/json/pull/2002) ([alexandermyasnikov](https://github.com/alexandermyasnikov)) +- catch exceptions for json\_pointer : ..../+99 [\#1990](https://github.com/nlohmann/json/pull/1990) ([dota17](https://github.com/dota17)) +- Modify the document about operator== [\#1984](https://github.com/nlohmann/json/pull/1984) ([dota17](https://github.com/dota17)) +- Rename argument array\_index to array\_indx in json\_pointer methods [\#1980](https://github.com/nlohmann/json/pull/1980) ([linev](https://github.com/linev)) +- README: Fix string representation of `dump`ed `json` [\#1979](https://github.com/nlohmann/json/pull/1979) ([alexweej](https://github.com/alexweej)) +- fix warnings in serializer.hpp for VS2019 [\#1969](https://github.com/nlohmann/json/pull/1969) ([dota17](https://github.com/dota17)) +- Fix C26451 warnnings in to\_chars.hpp [\#1967](https://github.com/nlohmann/json/pull/1967) ([dota17](https://github.com/dota17)) +- appveyor.yml: Compile and test with latest version for \_\_cplusplus ma… [\#1958](https://github.com/nlohmann/json/pull/1958) ([t-b](https://github.com/t-b)) +- Fix typo in examples [\#1956](https://github.com/nlohmann/json/pull/1956) ([dota17](https://github.com/dota17)) +- templated input adapters [\#1950](https://github.com/nlohmann/json/pull/1950) ([FrancoisChabot](https://github.com/FrancoisChabot)) +- Update README.md : add a FAQ about memory release [\#1933](https://github.com/nlohmann/json/pull/1933) ([dota17](https://github.com/dota17)) +- Some typos [\#1923](https://github.com/nlohmann/json/pull/1923) ([Coeur](https://github.com/Coeur)) +- Fix link to parse function in README [\#1918](https://github.com/nlohmann/json/pull/1918) ([kastiglione](https://github.com/kastiglione)) +- Readme: Updated links to hunter repo & docs [\#1917](https://github.com/nlohmann/json/pull/1917) ([jothepro](https://github.com/jothepro)) +- Adds instruction for using Build2's package manager [\#1909](https://github.com/nlohmann/json/pull/1909) ([Klaim](https://github.com/Klaim)) +- Update README.md [\#1907](https://github.com/nlohmann/json/pull/1907) ([pauljurczak](https://github.com/pauljurczak)) +- Fix warning: ignoring return value [\#1871](https://github.com/nlohmann/json/pull/1871) ([sonulohani](https://github.com/sonulohani)) +- docs: add central repository as conan source to readme [\#1857](https://github.com/nlohmann/json/pull/1857) ([gocarlos](https://github.com/gocarlos)) +- README: Package in MSYS2 renamed to nlohmann-json [\#1853](https://github.com/nlohmann/json/pull/1853) ([podsvirov](https://github.com/podsvirov)) +- Fix msvc warnings [\#1846](https://github.com/nlohmann/json/pull/1846) ([MBalszun](https://github.com/MBalszun)) +- Update tests that generate CMake projects to use main project's C++ compiler [\#1844](https://github.com/nlohmann/json/pull/1844) ([Tridacnid](https://github.com/Tridacnid)) +- make CMake's version config file architecture-independent [\#1746](https://github.com/nlohmann/json/pull/1746) ([uhoreg](https://github.com/uhoreg)) +- Add binary type support to all binary file formats, as well as an internally represented binary type [\#1662](https://github.com/nlohmann/json/pull/1662) ([OmnipotentEntity](https://github.com/OmnipotentEntity)) + +## [v3.7.3](https://github.com/nlohmann/json/releases/tag/v3.7.3) (2019-11-17) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.2...v3.7.3) + +- Project branches [\#1839](https://github.com/nlohmann/json/issues/1839) +- Quadratic destruction complexity introduced in \#1436 [\#1837](https://github.com/nlohmann/json/issues/1837) +- Trying to open a file [\#1814](https://github.com/nlohmann/json/issues/1814) +- Comparing data type with value\_t::number\_integer fails [\#1783](https://github.com/nlohmann/json/issues/1783) +- CMake version config file is architecture-dependent [\#1697](https://github.com/nlohmann/json/issues/1697) + +- Fix quadratic destruction complexity [\#1838](https://github.com/nlohmann/json/pull/1838) ([nickaein](https://github.com/nickaein)) + +## [v3.7.2](https://github.com/nlohmann/json/releases/tag/v3.7.2) (2019-11-10) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.1...v3.7.2) + +- Segmentation fault in destructor in case of large inputs [\#1835](https://github.com/nlohmann/json/issues/1835) +- type\_name\(\) is not consistent with type\(\) [\#1833](https://github.com/nlohmann/json/issues/1833) +- json::parse is not a member [\#1832](https://github.com/nlohmann/json/issues/1832) +- How do you deal with json\* ? [\#1829](https://github.com/nlohmann/json/issues/1829) +- Combined find\_package/add\_subdirectory not linking libraries [\#1771](https://github.com/nlohmann/json/issues/1771) +- example code for ifstream reading a json file results in no operator error [\#1766](https://github.com/nlohmann/json/issues/1766) +- Warning: unsequenced modification and access to 'range' [\#1674](https://github.com/nlohmann/json/issues/1674) +- Segmentation fault \(stack overflow\) due to unbounded recursion [\#1419](https://github.com/nlohmann/json/issues/1419) +- Stack-overflow \(OSS-Fuzz 4234\) [\#832](https://github.com/nlohmann/json/issues/832) + +- Configure WhiteSource Bolt for GitHub [\#1830](https://github.com/nlohmann/json/pull/1830) ([mend-bolt-for-github[bot]](https://github.com/apps/mend-bolt-for-github)) +- Prevent stackoverflow caused by recursive deconstruction [\#1436](https://github.com/nlohmann/json/pull/1436) ([nickaein](https://github.com/nickaein)) + +## [v3.7.1](https://github.com/nlohmann/json/releases/tag/v3.7.1) (2019-11-06) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.0...v3.7.1) + +- std::is\_constructible is always true with tuple [\#1825](https://github.com/nlohmann/json/issues/1825) +- Can't compile from\_json\(std::valarray\\). [\#1824](https://github.com/nlohmann/json/issues/1824) +- json class should have a get\_or member function [\#1823](https://github.com/nlohmann/json/issues/1823) +- NLOHMANN\_JSON\_SERIALIZE\_ENUM macro capture's json objects by value [\#1822](https://github.com/nlohmann/json/issues/1822) +- Parse fails when number literals start with zero [\#1820](https://github.com/nlohmann/json/issues/1820) +- Weird behaviour of `contains` with `json_pointer` [\#1815](https://github.com/nlohmann/json/issues/1815) +- strange behaviour with json\_pointer and .contains\(\) [\#1811](https://github.com/nlohmann/json/issues/1811) +- Can \#1695 be re-opened? [\#1808](https://github.com/nlohmann/json/issues/1808) +- Merge two json objects [\#1807](https://github.com/nlohmann/json/issues/1807) +- std::is\_constructible\\> when to\_json not defined [\#1805](https://github.com/nlohmann/json/issues/1805) +- Private data on parsing [\#1802](https://github.com/nlohmann/json/issues/1802) +- Capturing Line and Position when querying [\#1800](https://github.com/nlohmann/json/issues/1800) +- json error on parsing DBL\_MAX from string [\#1796](https://github.com/nlohmann/json/issues/1796) +- De/Serialisation of vector of tupple object with nested obect need Help please [\#1794](https://github.com/nlohmann/json/issues/1794) +- Output json is corrupted [\#1793](https://github.com/nlohmann/json/issues/1793) +- variable name byte sometimes used as a \#define [\#1792](https://github.com/nlohmann/json/issues/1792) +- Can't read json file [\#1791](https://github.com/nlohmann/json/issues/1791) +- Problems with special German letters [\#1789](https://github.com/nlohmann/json/issues/1789) +- Support for trailing commas [\#1787](https://github.com/nlohmann/json/issues/1787) +- json\_pointer construction bug [\#1786](https://github.com/nlohmann/json/issues/1786) +- Visual Studio 2017 warning [\#1784](https://github.com/nlohmann/json/issues/1784) +- ciso646 header become obsolete [\#1782](https://github.com/nlohmann/json/issues/1782) +- Migrate LGTM.com installation from OAuth to GitHub App [\#1781](https://github.com/nlohmann/json/issues/1781) +- JSON comparison, contains and operator& [\#1778](https://github.com/nlohmann/json/issues/1778) +- pass a json object to a class contructor adds an array around the object [\#1776](https://github.com/nlohmann/json/issues/1776) +- 'Float' number\_float\_function\_t template parameter name conflicts with C '\#define Float float' [\#1775](https://github.com/nlohmann/json/issues/1775) +- A weird building problem :-\( [\#1774](https://github.com/nlohmann/json/issues/1774) +- What is this json\_ref? [\#1772](https://github.com/nlohmann/json/issues/1772) +- Interoperability with other languages [\#1770](https://github.com/nlohmann/json/issues/1770) +- Json dump [\#1768](https://github.com/nlohmann/json/issues/1768) +- json\_pointer\<\>::back\(\) should be const [\#1764](https://github.com/nlohmann/json/issues/1764) +- How to get value from array [\#1762](https://github.com/nlohmann/json/issues/1762) +- Merge two jsons [\#1757](https://github.com/nlohmann/json/issues/1757) +- Unable to locate nlohmann\_jsonConfig.cmake [\#1755](https://github.com/nlohmann/json/issues/1755) +- json.hpp won;t compile VS2019 CLR/CLI app but does in console app [\#1754](https://github.com/nlohmann/json/issues/1754) +- \[Nested Json Objects\] Segmentation fault [\#1753](https://github.com/nlohmann/json/issues/1753) +- remove/replace assert with exceptions [\#1752](https://github.com/nlohmann/json/issues/1752) +- Add array support for update\(\) function [\#1751](https://github.com/nlohmann/json/issues/1751) +- Is there a reason the `get_to` method is defined in `include/nlohmann/json.hpp` but not in `single_include/nlohmann/json.hpp`? [\#1750](https://github.com/nlohmann/json/issues/1750) +- how to validate json object before calling dump\(\) [\#1748](https://github.com/nlohmann/json/issues/1748) +- Unable to invoke accessors on json objects in lldb [\#1745](https://github.com/nlohmann/json/issues/1745) +- Escaping string before parsing [\#1743](https://github.com/nlohmann/json/issues/1743) +- Construction in a member initializer list using curly braces is set as 'array' [\#1742](https://github.com/nlohmann/json/issues/1742) +- Read a subkey from json object [\#1740](https://github.com/nlohmann/json/issues/1740) +- Serialize vector of glm:vec2 [\#1739](https://github.com/nlohmann/json/issues/1739) +- Support nlohmann::basic\_json::value with JSON\_NOEXCEPTION [\#1738](https://github.com/nlohmann/json/issues/1738) +- how to know the parse is error [\#1737](https://github.com/nlohmann/json/issues/1737) +- How to check if a given key exists in a JSON object [\#1736](https://github.com/nlohmann/json/issues/1736) +- Allow The Colon Key-Value Delimiter To Have A Space Before It \[@ READ ONLY\] [\#1735](https://github.com/nlohmann/json/issues/1735) +- Allow Tail { "Key": "Value" } Comma \[@ READ ONLY\] [\#1734](https://github.com/nlohmann/json/issues/1734) +- No-throw json::value\(\) [\#1733](https://github.com/nlohmann/json/issues/1733) +- JsonObject.dump\(\) [\#1732](https://github.com/nlohmann/json/issues/1732) +- basic\_json has no member "parse" [\#1731](https://github.com/nlohmann/json/issues/1731) +- Exception "type must be string, but is array" [\#1730](https://github.com/nlohmann/json/issues/1730) +- json::contains usage to find a path [\#1727](https://github.com/nlohmann/json/issues/1727) +- How to create JSON Object from my Structures of Data and Json File from that Object [\#1726](https://github.com/nlohmann/json/issues/1726) +- please provide an API to read JSON from file directly. [\#1725](https://github.com/nlohmann/json/issues/1725) +- How to modify a value stored at a key? [\#1723](https://github.com/nlohmann/json/issues/1723) +- CMake not correctly finding the configuration package for 3.7.0 [\#1721](https://github.com/nlohmann/json/issues/1721) +- name typo in the "spack package management" section of README.md [\#1720](https://github.com/nlohmann/json/issues/1720) +- How to add json to another json? [\#1718](https://github.com/nlohmann/json/issues/1718) +- json::parse\(\) ubsan regression with v3.7.0 [\#1716](https://github.com/nlohmann/json/issues/1716) +- What I am doing wrong?!? [\#1714](https://github.com/nlohmann/json/issues/1714) +- Potential memory leak detected by Valgrind [\#1713](https://github.com/nlohmann/json/issues/1713) +- json::parse is not thread safe? [\#1712](https://github.com/nlohmann/json/issues/1712) +- static analysis alarm by cppcheck [\#1711](https://github.com/nlohmann/json/issues/1711) +- The compilation time is slow [\#1710](https://github.com/nlohmann/json/issues/1710) +- not linking properly with cmake [\#1709](https://github.com/nlohmann/json/issues/1709) +- Error in dump\(\) with int64\_t minimum value [\#1708](https://github.com/nlohmann/json/issues/1708) +- Crash on trying to deserialize json string on 3ds homebrew [\#1707](https://github.com/nlohmann/json/issues/1707) +- Can't compile VS2019. 13 Errors [\#1706](https://github.com/nlohmann/json/issues/1706) +- find an object that matches the search criteria [\#1705](https://github.com/nlohmann/json/issues/1705) +- IntelliSense goes crazy on VS2019 [\#1704](https://github.com/nlohmann/json/issues/1704) +- Installing on Ubuntu 16.04 [\#1703](https://github.com/nlohmann/json/issues/1703) +- Where is json::parse now? [\#1702](https://github.com/nlohmann/json/issues/1702) +- Forward header should't be amalgamated [\#1700](https://github.com/nlohmann/json/issues/1700) +- Json support for Cmake version 2.8.12 [\#1699](https://github.com/nlohmann/json/issues/1699) +- Intruisive scientific notation when using .dump\(\); [\#1698](https://github.com/nlohmann/json/issues/1698) +- Is there support for automatic serialization/deserialization? [\#1696](https://github.com/nlohmann/json/issues/1696) +- on MSVC dump\(\) will hard crash for larger json [\#1693](https://github.com/nlohmann/json/issues/1693) +- puzzled implicit conversions [\#1692](https://github.com/nlohmann/json/issues/1692) +- Information: My project uses this awesome library [\#1691](https://github.com/nlohmann/json/issues/1691) +- Consider listing files explicitly instead of using GLOB [\#1686](https://github.com/nlohmann/json/issues/1686) +- Failing tests on MSVC with VS2019 15.9.13 x64 [\#1685](https://github.com/nlohmann/json/issues/1685) +- Change from v2 to v3. Encoding with cp1252 [\#1680](https://github.com/nlohmann/json/issues/1680) +- How to add Fifo\_map into json using Cmake [\#1679](https://github.com/nlohmann/json/issues/1679) +- include.zip should contain meson.build [\#1672](https://github.com/nlohmann/json/issues/1672) +- \[Question\] How do I parse JSON into custom types? [\#1669](https://github.com/nlohmann/json/issues/1669) +- Binary \(0x05\) data type for BSON to JSON conversion [\#1668](https://github.com/nlohmann/json/issues/1668) +- Possible to call dump from lldb? [\#1666](https://github.com/nlohmann/json/issues/1666) +- Segmentation fault when linked with libunwind [\#1665](https://github.com/nlohmann/json/issues/1665) +- Should I include single-header after my to\_json and from\_json custom functions declaration? Why not? [\#1663](https://github.com/nlohmann/json/issues/1663) +- Errors/Warnings in VS 2019 when Including Header File [\#1659](https://github.com/nlohmann/json/issues/1659) +- Return null object from object's const operator\[\] as well. [\#1658](https://github.com/nlohmann/json/issues/1658) +- Can't stream json object in to std::basic\_stringstream\ [\#1656](https://github.com/nlohmann/json/issues/1656) +- C2440 in vs2015 cannot convert from 'initializer-list' to nlohmann::basic\_json [\#1655](https://github.com/nlohmann/json/issues/1655) +- Issues around get and pointers [\#1653](https://github.com/nlohmann/json/issues/1653) +- Non-member operator== breaks enum \(de\)serialization [\#1647](https://github.com/nlohmann/json/issues/1647) +- Valgrind: bytes in 1 blocks are definitely lost [\#1646](https://github.com/nlohmann/json/issues/1646) +- Convenient way to make 'basic\_json' accept 'QString' as an key type as well? [\#1640](https://github.com/nlohmann/json/issues/1640) +- mongodb: nan, inf [\#1599](https://github.com/nlohmann/json/issues/1599) +- Error in adl\_serializer [\#1590](https://github.com/nlohmann/json/issues/1590) +- Injecting class during serialization [\#1584](https://github.com/nlohmann/json/issues/1584) +- output\_adapter not user extensible [\#1534](https://github.com/nlohmann/json/issues/1534) +- Inclusion of nlohmann/json.hpp causes OS/ABI to change on Linux [\#1410](https://github.com/nlohmann/json/issues/1410) +- Add library versioning using inline namespaces [\#1394](https://github.com/nlohmann/json/issues/1394) +- CBOR byte string support [\#1129](https://github.com/nlohmann/json/issues/1129) +- How to deserialize array with derived objects [\#716](https://github.com/nlohmann/json/issues/716) + +- Add restriction for tuple specialization of to\_json [\#1826](https://github.com/nlohmann/json/pull/1826) ([cbegue](https://github.com/cbegue)) +- Fix for \#1647 [\#1821](https://github.com/nlohmann/json/pull/1821) ([AnthonyVH](https://github.com/AnthonyVH)) +- Fix issue \#1805 [\#1806](https://github.com/nlohmann/json/pull/1806) ([cbegue](https://github.com/cbegue)) +- Fix some spelling errors - mostly in comments & documentation. [\#1803](https://github.com/nlohmann/json/pull/1803) ([flopp](https://github.com/flopp)) +- Update Hedley to v11. [\#1799](https://github.com/nlohmann/json/pull/1799) ([nemequ](https://github.com/nemequ)) +- iteration\_proxy: Fix integer truncation from std::size\_t to int [\#1797](https://github.com/nlohmann/json/pull/1797) ([t-b](https://github.com/t-b)) +- appveyor.yml: Add MSVC 16 2019 support [\#1780](https://github.com/nlohmann/json/pull/1780) ([t-b](https://github.com/t-b)) +- test/CMakeLists.txt: Use an explicit list instead of GLOB [\#1779](https://github.com/nlohmann/json/pull/1779) ([t-b](https://github.com/t-b)) +- Make json\_pointer::back const \(resolves \#1764\) [\#1769](https://github.com/nlohmann/json/pull/1769) ([chris0x44](https://github.com/chris0x44)) +- did you mean 'serialization'? [\#1767](https://github.com/nlohmann/json/pull/1767) ([0xflotus](https://github.com/0xflotus)) +- Allow items\(\) to be used with custom string [\#1765](https://github.com/nlohmann/json/pull/1765) ([crazyjul](https://github.com/crazyjul)) +- Cppcheck fixes [\#1760](https://github.com/nlohmann/json/pull/1760) ([Xav83](https://github.com/Xav83)) +- Fix and add test's for SFINAE problem [\#1741](https://github.com/nlohmann/json/pull/1741) ([tete17](https://github.com/tete17)) +- Fix clang sanitizer invocation [\#1728](https://github.com/nlohmann/json/pull/1728) ([t-b](https://github.com/t-b)) +- Add gcc 9 and compile with experimental C++20 support [\#1724](https://github.com/nlohmann/json/pull/1724) ([t-b](https://github.com/t-b)) +- Fix int64 min issue [\#1722](https://github.com/nlohmann/json/pull/1722) ([t-b](https://github.com/t-b)) +- release: add singleinclude and meson.build to include.zip [\#1694](https://github.com/nlohmann/json/pull/1694) ([eli-schwartz](https://github.com/eli-schwartz)) + +## [v3.7.0](https://github.com/nlohmann/json/releases/tag/v3.7.0) (2019-07-28) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.1...v3.7.0) + +- How can I retrieve uknown strings from json file in my C++ program. [\#1684](https://github.com/nlohmann/json/issues/1684) +- contains\(\) is sometimes causing stack-based buffer overrun exceptions [\#1683](https://github.com/nlohmann/json/issues/1683) +- How to deserialize arrays from json [\#1681](https://github.com/nlohmann/json/issues/1681) +- Compilation failed in VS2015 [\#1678](https://github.com/nlohmann/json/issues/1678) +- Why the compiled object file is so huge? [\#1677](https://github.com/nlohmann/json/issues/1677) +- From Version 2.1.1 to 3.6.1 serialize std::set [\#1676](https://github.com/nlohmann/json/issues/1676) +- Qt deprecation model halting compiltion [\#1675](https://github.com/nlohmann/json/issues/1675) +- Build For Raspberry pi , Rapbery with new Compiler C++17 [\#1671](https://github.com/nlohmann/json/issues/1671) +- Build from Raspberry pi [\#1667](https://github.com/nlohmann/json/issues/1667) +- Can not translate map with integer key to dict string ? [\#1664](https://github.com/nlohmann/json/issues/1664) +- Double type converts to scientific notation [\#1661](https://github.com/nlohmann/json/issues/1661) +- Missing v3.6.1 tag on master branch [\#1657](https://github.com/nlohmann/json/issues/1657) +- Support Fleese Binary Data Format [\#1654](https://github.com/nlohmann/json/issues/1654) +- Suggestion: replace alternative tokens for !, && and || with their symbols [\#1652](https://github.com/nlohmann/json/issues/1652) +- Build failure test-allocator.vcxproj [\#1651](https://github.com/nlohmann/json/issues/1651) +- How to provide function json& to\_json\(\) which is similar as 'void to\_json\(json&j, const CObject& obj\)' ? [\#1650](https://github.com/nlohmann/json/issues/1650) +- Can't throw exception when starting file is a number [\#1649](https://github.com/nlohmann/json/issues/1649) +- to\_json / from\_json with nested type [\#1648](https://github.com/nlohmann/json/issues/1648) +- How to create a json object from a std::string, created by j.dump? [\#1645](https://github.com/nlohmann/json/issues/1645) +- Problem getting vector \(array\) of strings [\#1644](https://github.com/nlohmann/json/issues/1644) +- json.hpp compilation issue with other typedefs with same name [\#1642](https://github.com/nlohmann/json/issues/1642) +- nlohmann::adl\_serializer\::to\_json no matching overloaded function found [\#1641](https://github.com/nlohmann/json/issues/1641) +- overwrite adl\_serializer\ to change behaviour [\#1638](https://github.com/nlohmann/json/issues/1638) +- json.SelectToken\("Manufacturers.Products.Price"\); [\#1637](https://github.com/nlohmann/json/issues/1637) +- Add json type as value [\#1636](https://github.com/nlohmann/json/issues/1636) +- Unit conversion test error: conversion from 'nlohmann::json' to non-scalar type 'std::string\_view' requested [\#1634](https://github.com/nlohmann/json/issues/1634) +- nlohmann VS JsonCpp by C++17 [\#1633](https://github.com/nlohmann/json/issues/1633) +- To integrate an inline helper function that return type name as string [\#1632](https://github.com/nlohmann/json/issues/1632) +- Return JSON as reference [\#1631](https://github.com/nlohmann/json/issues/1631) +- Updating from an older version causes problems with assing a json object to a struct [\#1630](https://github.com/nlohmann/json/issues/1630) +- Can without default constructor function for user defined classes when only to\_json is needed? [\#1629](https://github.com/nlohmann/json/issues/1629) +- Compilation fails with clang 6.x-8.x in C++14 mode [\#1628](https://github.com/nlohmann/json/issues/1628) +- Treating floating point as string [\#1627](https://github.com/nlohmann/json/issues/1627) +- error parsing character å [\#1626](https://github.com/nlohmann/json/issues/1626) +- \[Help\] How to Improve Json Output Performance with Large Json Arrays [\#1624](https://github.com/nlohmann/json/issues/1624) +- Suggested link changes for reporting new issues \[blob/develop/REAME.md and blob/develop/.github/CONTRIBUTING.md\] [\#1623](https://github.com/nlohmann/json/issues/1623) +- Broken link to issue template in CONTRIBUTING.md [\#1622](https://github.com/nlohmann/json/issues/1622) +- Missing word in README.md file [\#1621](https://github.com/nlohmann/json/issues/1621) +- Package manager instructions in README for brew is incorrect [\#1620](https://github.com/nlohmann/json/issues/1620) +- Building with Visual Studio 2019 [\#1619](https://github.com/nlohmann/json/issues/1619) +- Precedence of to\_json and builtin harmful [\#1617](https://github.com/nlohmann/json/issues/1617) +- The type json is missing from the html documentation [\#1616](https://github.com/nlohmann/json/issues/1616) +- variant is not support in Release 3.6.1? [\#1615](https://github.com/nlohmann/json/issues/1615) +- Replace assert with throw for const operator\[\] [\#1614](https://github.com/nlohmann/json/issues/1614) +- Memory Overhead is Too High \(10x or more\) [\#1613](https://github.com/nlohmann/json/issues/1613) +- program crash everytime, when other data type incomming in json stream as expected [\#1612](https://github.com/nlohmann/json/issues/1612) +- Improved Enum Support [\#1611](https://github.com/nlohmann/json/issues/1611) +- is it possible convert json object back to stl container ? [\#1610](https://github.com/nlohmann/json/issues/1610) +- Add C++17-like emplace.back\(\) for arrays. [\#1609](https://github.com/nlohmann/json/issues/1609) +- is\_nothrow\_copy\_constructible fails for json::const\_iterator on MSVC2015 x86 Debug build [\#1608](https://github.com/nlohmann/json/issues/1608) +- Reading and writing array elements [\#1607](https://github.com/nlohmann/json/issues/1607) +- Converting json::value to int [\#1605](https://github.com/nlohmann/json/issues/1605) +- I have a vector of keys and and a string of value and i want to create nested json array [\#1604](https://github.com/nlohmann/json/issues/1604) +- In compatible JSON object from nlohmann::json to nohman::json - unexpected end of input; expected '\[', '{', or a literal [\#1603](https://github.com/nlohmann/json/issues/1603) +- json parser crash if having a large number integer in message [\#1602](https://github.com/nlohmann/json/issues/1602) +- Value method with undocumented throwing 302 exception [\#1601](https://github.com/nlohmann/json/issues/1601) +- Accessing value with json pointer adds key if not existing [\#1600](https://github.com/nlohmann/json/issues/1600) +- README.md broken link to project documentation [\#1597](https://github.com/nlohmann/json/issues/1597) +- Random Kudos: Thanks for your work on this! [\#1596](https://github.com/nlohmann/json/issues/1596) +- json::parse return value and errors [\#1595](https://github.com/nlohmann/json/issues/1595) +- initializer list constructor makes curly brace initialization fragile [\#1594](https://github.com/nlohmann/json/issues/1594) +- trying to log message for missing keyword, difference between \["foo"\] and at\("foo"\) [\#1593](https://github.com/nlohmann/json/issues/1593) +- std::string and std::wstring `to_json` [\#1592](https://github.com/nlohmann/json/issues/1592) +- I have a C structure which I need to convert to a JSON. How do I do it? Haven't found proper examples so far. [\#1591](https://github.com/nlohmann/json/issues/1591) +- dump\_escaped possible error ? [\#1589](https://github.com/nlohmann/json/issues/1589) +- json::parse\(\) into a vector\ results in unhandled exception [\#1587](https://github.com/nlohmann/json/issues/1587) +- push\_back\(\)/emplace\_back\(\) on array invalidates pointers to existing array items [\#1586](https://github.com/nlohmann/json/issues/1586) +- Getting nlohmann::detail::parse\_error on JSON generated by nlohmann::json not sure why [\#1583](https://github.com/nlohmann/json/issues/1583) +- getting error terminate called after throwing an instance of 'std::domain\_error' what\(\): cannot use at\(\) with string [\#1582](https://github.com/nlohmann/json/issues/1582) +- how i create json file [\#1581](https://github.com/nlohmann/json/issues/1581) +- prevent rounding of double datatype values [\#1580](https://github.com/nlohmann/json/issues/1580) +- Documentation Container Overview Doesn't Reference Const Methods [\#1579](https://github.com/nlohmann/json/issues/1579) +- Writing an array into a nlohmann::json object [\#1578](https://github.com/nlohmann/json/issues/1578) +- compilation error when using with another library [\#1577](https://github.com/nlohmann/json/issues/1577) +- Homebrew on OSX doesn't install cmake config file [\#1576](https://github.com/nlohmann/json/issues/1576) +- JSON Parse Out of Range Error [\#1574](https://github.com/nlohmann/json/issues/1574) +- Integrating into existing CMake Project [\#1573](https://github.com/nlohmann/json/issues/1573) +- conversion to std::string failed [\#1571](https://github.com/nlohmann/json/issues/1571) +- jPtr operation does not throw [\#1569](https://github.com/nlohmann/json/issues/1569) +- How to generate dll file for this project [\#1568](https://github.com/nlohmann/json/issues/1568) +- how to pass variable data to json in c [\#1567](https://github.com/nlohmann/json/issues/1567) +- I want to achieve an upgraded function. [\#1566](https://github.com/nlohmann/json/issues/1566) +- How to determine the type of elements read from a JSON array? [\#1564](https://github.com/nlohmann/json/issues/1564) +- try\_get\_to [\#1563](https://github.com/nlohmann/json/issues/1563) +- example code compile error [\#1562](https://github.com/nlohmann/json/issues/1562) +- How to iterate over nested json object [\#1561](https://github.com/nlohmann/json/issues/1561) +- Build Option/Separate Function to Allow to Throw on Duplicate Keys [\#1560](https://github.com/nlohmann/json/issues/1560) +- Compiler Switches -Weffc++ & -Wshadow are throwing errors [\#1558](https://github.com/nlohmann/json/issues/1558) +- warning: use of the 'nodiscard' attribute is a C++17 extension [\#1557](https://github.com/nlohmann/json/issues/1557) +- Import/Export compressed JSON files [\#1556](https://github.com/nlohmann/json/issues/1556) +- GDB renderers for json library [\#1554](https://github.com/nlohmann/json/issues/1554) +- Is it possible to construct a json string object from a binary buffer? [\#1553](https://github.com/nlohmann/json/issues/1553) +- json objects in list [\#1552](https://github.com/nlohmann/json/issues/1552) +- Matrix output [\#1550](https://github.com/nlohmann/json/issues/1550) +- Using json merge\_patch on ordered non-alphanumeric datasets [\#1549](https://github.com/nlohmann/json/issues/1549) +- Invalid parsed value for big integer [\#1548](https://github.com/nlohmann/json/issues/1548) +- Integrating with android ndk issues. [\#1547](https://github.com/nlohmann/json/issues/1547) +- add noexcept json::value\("key", default\) method variant? [\#1546](https://github.com/nlohmann/json/issues/1546) +- Thank you! 🙌 [\#1545](https://github.com/nlohmann/json/issues/1545) +- Output and input matrix [\#1544](https://github.com/nlohmann/json/issues/1544) +- Add regression tests for MSVC [\#1543](https://github.com/nlohmann/json/issues/1543) +- \[Help Needed!\] Season of Docs [\#1542](https://github.com/nlohmann/json/issues/1542) +- program still abort\(\) or exit\(\) with try catch [\#1541](https://github.com/nlohmann/json/issues/1541) +- Have a json::type\_error exception because of JSON object [\#1540](https://github.com/nlohmann/json/issues/1540) +- Quoted numbers [\#1538](https://github.com/nlohmann/json/issues/1538) +- Reading a JSON file into an object [\#1537](https://github.com/nlohmann/json/issues/1537) +- Releases 3.6.0 and 3.6.1 don't build on conda / windows [\#1536](https://github.com/nlohmann/json/issues/1536) +- \[Clang\] warning: use of the 'nodiscard' attribute is a C++17 extension \[-Wc++17-extensions\] [\#1535](https://github.com/nlohmann/json/issues/1535) +- wchar\_t/std::wstring json can be created but not accessed [\#1533](https://github.com/nlohmann/json/issues/1533) +- json stringify [\#1532](https://github.com/nlohmann/json/issues/1532) +- How can I use it from gcc on RPI [\#1528](https://github.com/nlohmann/json/issues/1528) +- std::pair treated as an array instead of key-value in `std::vector>` [\#1520](https://github.com/nlohmann/json/issues/1520) +- Excessive Memory Usage for Large Json File [\#1516](https://github.com/nlohmann/json/issues/1516) +- SAX dumper [\#1512](https://github.com/nlohmann/json/issues/1512) +- Conversion to user type containing a std::vector not working with documented approach [\#1511](https://github.com/nlohmann/json/issues/1511) +- Inconsistent use of type alias. [\#1507](https://github.com/nlohmann/json/issues/1507) +- Is there a current way to represent strings as json int? [\#1503](https://github.com/nlohmann/json/issues/1503) +- Intermittent issues with loadJSON [\#1484](https://github.com/nlohmann/json/issues/1484) +- use json construct std::string [\#1462](https://github.com/nlohmann/json/issues/1462) +- JSON Creation [\#1461](https://github.com/nlohmann/json/issues/1461) +- Null bytes in files are treated like EOF [\#1095](https://github.com/nlohmann/json/issues/1095) +- Feature: to\_string\(const json& j\); [\#916](https://github.com/nlohmann/json/issues/916) + +- Use GNUInstallDirs instead of hard-coded path. [\#1673](https://github.com/nlohmann/json/pull/1673) ([ghost](https://github.com/ghost)) +- Package Manager: MSYS2 \(pacman\) [\#1670](https://github.com/nlohmann/json/pull/1670) ([podsvirov](https://github.com/podsvirov)) +- Fix json.hpp compilation issue with other typedefs with same name \(Issue \#1642\) [\#1643](https://github.com/nlohmann/json/pull/1643) ([kevinlul](https://github.com/kevinlul)) +- Add explicit conversion from json to std::string\_view in conversion unit test [\#1639](https://github.com/nlohmann/json/pull/1639) ([taylorhoward92](https://github.com/taylorhoward92)) +- Minor fixes in docs [\#1625](https://github.com/nlohmann/json/pull/1625) ([nickaein](https://github.com/nickaein)) +- Fix broken links to documentation [\#1598](https://github.com/nlohmann/json/pull/1598) ([nickaein](https://github.com/nickaein)) +- Added to\_string and added basic tests [\#1585](https://github.com/nlohmann/json/pull/1585) ([Macr0Nerd](https://github.com/Macr0Nerd)) +- Regression tests for MSVC [\#1570](https://github.com/nlohmann/json/pull/1570) ([nickaein](https://github.com/nickaein)) +- Fix/1511 [\#1555](https://github.com/nlohmann/json/pull/1555) ([theodelrieu](https://github.com/theodelrieu)) +- Remove C++17 extension warning from clang; \#1535 [\#1551](https://github.com/nlohmann/json/pull/1551) ([heavywatal](https://github.com/heavywatal)) +- moved from Catch to doctest for unit tests [\#1439](https://github.com/nlohmann/json/pull/1439) ([onqtam](https://github.com/onqtam)) + +## [v3.6.1](https://github.com/nlohmann/json/releases/tag/v3.6.1) (2019-03-20) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.6.1...v3.6.1) + +## [3.6.1](https://github.com/nlohmann/json/releases/tag/3.6.1) (2019-03-20) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.0...3.6.1) + +- Failed to build with \ [\#1531](https://github.com/nlohmann/json/issues/1531) +- Compiling 3.6.0 with GCC \> 7, array vs std::array \#590 is back [\#1530](https://github.com/nlohmann/json/issues/1530) +- 3.6.0: warning: missing initializer for member 'std::array\::\_M\_elems' \[-Wmissing-field-initializers\] [\#1527](https://github.com/nlohmann/json/issues/1527) +- unable to parse json [\#1525](https://github.com/nlohmann/json/issues/1525) + +## [v3.6.0](https://github.com/nlohmann/json/releases/tag/v3.6.0) (2019-03-19) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.5.0...v3.6.0) + +- How can I turn a string of a json array into a json array? [\#1526](https://github.com/nlohmann/json/issues/1526) +- Minor: missing a std:: namespace tag [\#1521](https://github.com/nlohmann/json/issues/1521) +- how to precision to four decimal for double when use to\_json [\#1519](https://github.com/nlohmann/json/issues/1519) +- error parse [\#1518](https://github.com/nlohmann/json/issues/1518) +- Compile error: template argument deduction/substitution failed [\#1515](https://github.com/nlohmann/json/issues/1515) +- std::complex type [\#1510](https://github.com/nlohmann/json/issues/1510) +- CBOR byte string support [\#1509](https://github.com/nlohmann/json/issues/1509) +- Compilation error getting a std::pair\<\> on latest VS 2017 compiler [\#1506](https://github.com/nlohmann/json/issues/1506) +- "Integration" section of documentation needs update? [\#1505](https://github.com/nlohmann/json/issues/1505) +- Json object from string from a TCP socket [\#1504](https://github.com/nlohmann/json/issues/1504) +- MSVC warning C4946 \("reinterpret\_cast used between related classes"\) compiling json.hpp [\#1502](https://github.com/nlohmann/json/issues/1502) +- How to programmatically fill an n-th dimensional JSON object? [\#1501](https://github.com/nlohmann/json/issues/1501) +- Error compiling with clang and `JSON_NOEXCEPTION`: need to include `cstdlib` [\#1500](https://github.com/nlohmann/json/issues/1500) +- The code compiles unsuccessfully with android-ndk-r10e [\#1499](https://github.com/nlohmann/json/issues/1499) +- Cmake 3.1 in develop, when is it likely to make it into a stable release? [\#1498](https://github.com/nlohmann/json/issues/1498) +- Some Help please object inside array [\#1494](https://github.com/nlohmann/json/issues/1494) +- How to get data into vector of user-defined type from a Json object [\#1493](https://github.com/nlohmann/json/issues/1493) +- how to find subelement without loop [\#1490](https://github.com/nlohmann/json/issues/1490) +- json to std::map [\#1487](https://github.com/nlohmann/json/issues/1487) +- Type in README.md [\#1486](https://github.com/nlohmann/json/issues/1486) +- Error in parsing and reading msgpack-lite [\#1485](https://github.com/nlohmann/json/issues/1485) +- Compiling issues with libc 2.12 [\#1483](https://github.com/nlohmann/json/issues/1483) +- How do I use reference or pointer binding values? [\#1482](https://github.com/nlohmann/json/issues/1482) +- Compilation fails in MSVC with the Microsoft Language Extensions disabled [\#1481](https://github.com/nlohmann/json/issues/1481) +- Functional visit [\#1480](https://github.com/nlohmann/json/issues/1480) +- \[Question\] Unescaped dump [\#1479](https://github.com/nlohmann/json/issues/1479) +- Some Help please [\#1478](https://github.com/nlohmann/json/issues/1478) +- Global variables are stored within the JSON file, how do I declare them as global variables when I read them out in my C++ program? [\#1476](https://github.com/nlohmann/json/issues/1476) +- Unable to modify one of the values within the JSON file, and save it [\#1475](https://github.com/nlohmann/json/issues/1475) +- Documentation of parse function has two identical @pre causes [\#1473](https://github.com/nlohmann/json/issues/1473) +- GCC 9.0 build failure [\#1472](https://github.com/nlohmann/json/issues/1472) +- Can we have an `exists()` method? [\#1471](https://github.com/nlohmann/json/issues/1471) +- How to parse multi object json from file? [\#1470](https://github.com/nlohmann/json/issues/1470) +- How to returns the name of the upper object? [\#1467](https://github.com/nlohmann/json/issues/1467) +- Error: "tuple\_size" has already been declared in the current scope [\#1466](https://github.com/nlohmann/json/issues/1466) +- Checking keys of two jsons against eachother [\#1465](https://github.com/nlohmann/json/issues/1465) +- Disable installation when used as meson subproject [\#1463](https://github.com/nlohmann/json/issues/1463) +- Unpack list of integers to a std::vector\ [\#1460](https://github.com/nlohmann/json/issues/1460) +- Implement DRY definition of JSON representation of a c++ class [\#1459](https://github.com/nlohmann/json/issues/1459) +- json.exception.type\_error.305 with GCC 4.9 when using C++ {} initializer [\#1458](https://github.com/nlohmann/json/issues/1458) +- API to convert an "uninitialized" json into an empty object or empty array [\#1456](https://github.com/nlohmann/json/issues/1456) +- How to parse a vector of objects with const attributes [\#1453](https://github.com/nlohmann/json/issues/1453) +- NLOHMANN\_JSON\_SERIALIZE\_ENUM potentially requires duplicate definitions [\#1450](https://github.com/nlohmann/json/issues/1450) +- Question about making json object from file directory [\#1449](https://github.com/nlohmann/json/issues/1449) +- .get\(\) throws error if used with userdefined structs in unordered\_map [\#1448](https://github.com/nlohmann/json/issues/1448) +- Integer Overflow \(OSS-Fuzz 12506\) [\#1447](https://github.com/nlohmann/json/issues/1447) +- If a string has too many invalid UTF-8 characters, json::dump attempts to index an array out of bounds. [\#1445](https://github.com/nlohmann/json/issues/1445) +- Setting values of .JSON file [\#1444](https://github.com/nlohmann/json/issues/1444) +- alias object\_t::key\_type in basic\_json [\#1442](https://github.com/nlohmann/json/issues/1442) +- Latest Ubuntu package is 2.1.1 [\#1438](https://github.com/nlohmann/json/issues/1438) +- lexer.hpp\(1363\) '\_snprintf': is not a member | Visualstudio 2017 [\#1437](https://github.com/nlohmann/json/issues/1437) +- Static method invites inadvertent logic error. [\#1433](https://github.com/nlohmann/json/issues/1433) +- EOS compilation produces "fatal error: 'nlohmann/json.hpp' file not found" [\#1432](https://github.com/nlohmann/json/issues/1432) +- Support for bad commas [\#1429](https://github.com/nlohmann/json/issues/1429) +- Please have one base exception class for all json exceptions [\#1427](https://github.com/nlohmann/json/issues/1427) +- Compilation warning: 'tuple\_size' defined as a class template here but previously declared as a struct template [\#1426](https://github.com/nlohmann/json/issues/1426) +- Which version can be used with GCC 4.8.2 ? [\#1424](https://github.com/nlohmann/json/issues/1424) +- Ignore nullptr values on constructing json object from a container [\#1422](https://github.com/nlohmann/json/issues/1422) +- Support for custom float precision via unquoted strings [\#1421](https://github.com/nlohmann/json/issues/1421) +- It is possible to call `json::find` with a json\_pointer as argument. This causes runtime UB/crash. [\#1418](https://github.com/nlohmann/json/issues/1418) +- Dump throwing exception [\#1416](https://github.com/nlohmann/json/issues/1416) +- Build error [\#1415](https://github.com/nlohmann/json/issues/1415) +- Append version to include.zip [\#1412](https://github.com/nlohmann/json/issues/1412) +- error C2039: '\_snprintf': is not a member of 'std' - Windows [\#1408](https://github.com/nlohmann/json/issues/1408) +- Deserializing to vector [\#1407](https://github.com/nlohmann/json/issues/1407) +- Efficient way to set a `json` object as value into another `json` key [\#1406](https://github.com/nlohmann/json/issues/1406) +- Document return value of parse\(\) when allow\_exceptions == false and parsing fails [\#1405](https://github.com/nlohmann/json/issues/1405) +- Unexpected behaviour with structured binding [\#1404](https://github.com/nlohmann/json/issues/1404) +- Which native types does get\\(\) allow? [\#1403](https://github.com/nlohmann/json/issues/1403) +- Add something like Json::StaticString [\#1402](https://github.com/nlohmann/json/issues/1402) +- -Wmismatched-tags in 3.5.0? [\#1401](https://github.com/nlohmann/json/issues/1401) +- Coverity Scan reports an UNCAUGHT\_EXCEPT issue [\#1400](https://github.com/nlohmann/json/issues/1400) +- fff [\#1399](https://github.com/nlohmann/json/issues/1399) +- sorry this is not an issue, just a Question, How to change a key value in a file and save it ? [\#1398](https://github.com/nlohmann/json/issues/1398) +- appveyor x64 builds appear to be using Win32 toolset [\#1374](https://github.com/nlohmann/json/issues/1374) +- Serializing/Deserializing a Class containing a vector of itself [\#1373](https://github.com/nlohmann/json/issues/1373) +- Retrieving array elements. [\#1369](https://github.com/nlohmann/json/issues/1369) +- Deserialize [\#1366](https://github.com/nlohmann/json/issues/1366) +- call of overloaded for push\_back and operator+= is ambiguous [\#1352](https://github.com/nlohmann/json/issues/1352) +- got an error and cann't figure it out [\#1351](https://github.com/nlohmann/json/issues/1351) +- Improve number-to-string conversion [\#1334](https://github.com/nlohmann/json/issues/1334) +- Implicit type conversion error on MSVC [\#1333](https://github.com/nlohmann/json/issues/1333) +- NuGet Package [\#1132](https://github.com/nlohmann/json/issues/1132) + +- Change macros to numeric\_limits [\#1514](https://github.com/nlohmann/json/pull/1514) ([naszta](https://github.com/naszta)) +- fix GCC 7.1.1 - 7.2.1 on CentOS [\#1496](https://github.com/nlohmann/json/pull/1496) ([lieff](https://github.com/lieff)) +- Update Buckaroo instructions in README.md [\#1495](https://github.com/nlohmann/json/pull/1495) ([njlr](https://github.com/njlr)) +- Fix gcc9 build error test/src/unit-allocator.cpp \(Issue \#1472\) [\#1492](https://github.com/nlohmann/json/pull/1492) ([stac47](https://github.com/stac47)) +- Fix typo in README.md [\#1491](https://github.com/nlohmann/json/pull/1491) ([nickaein](https://github.com/nickaein)) +- Do proper endian conversions [\#1489](https://github.com/nlohmann/json/pull/1489) ([andreas-schwab](https://github.com/andreas-schwab)) +- Fix documentation [\#1477](https://github.com/nlohmann/json/pull/1477) ([nickaein](https://github.com/nickaein)) +- Implement contains\(\) member function [\#1474](https://github.com/nlohmann/json/pull/1474) ([nickaein](https://github.com/nickaein)) +- Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers [\#1469](https://github.com/nlohmann/json/pull/1469) ([garethsb](https://github.com/garethsb)) +- Disable Clang -Wmismatched-tags warning on tuple\_size / tuple\_element [\#1468](https://github.com/nlohmann/json/pull/1468) ([past-due](https://github.com/past-due)) +- Disable installation when used as meson subproject. \#1463 [\#1464](https://github.com/nlohmann/json/pull/1464) ([elvisoric](https://github.com/elvisoric)) +- docs: README typo [\#1455](https://github.com/nlohmann/json/pull/1455) ([wythe](https://github.com/wythe)) +- remove extra semicolon from readme [\#1451](https://github.com/nlohmann/json/pull/1451) ([Afforix](https://github.com/Afforix)) +- attempt to fix \#1445, flush buffer in serializer::dump\_escaped in UTF8\_REJECT case. [\#1446](https://github.com/nlohmann/json/pull/1446) ([scinart](https://github.com/scinart)) +- Use C++11 features supported by CMake 3.1. [\#1441](https://github.com/nlohmann/json/pull/1441) ([iwanders](https://github.com/iwanders)) +- :rotating\_light: fixed unused variable warning [\#1435](https://github.com/nlohmann/json/pull/1435) ([pboettch](https://github.com/pboettch)) +- allow push\_back\(\) and pop\_back\(\) calls on json\_pointer [\#1434](https://github.com/nlohmann/json/pull/1434) ([pboettch](https://github.com/pboettch)) +- Add instructions about using nlohmann/json with the conda package manager [\#1430](https://github.com/nlohmann/json/pull/1430) ([nicoddemus](https://github.com/nicoddemus)) +- Updated year in README.md [\#1425](https://github.com/nlohmann/json/pull/1425) ([jef](https://github.com/jef)) +- Fixed broken links in the README file [\#1423](https://github.com/nlohmann/json/pull/1423) ([skypjack](https://github.com/skypjack)) +- Fixed broken links in the README file [\#1420](https://github.com/nlohmann/json/pull/1420) ([skypjack](https://github.com/skypjack)) +- docs: typo in README [\#1417](https://github.com/nlohmann/json/pull/1417) ([wythe](https://github.com/wythe)) +- Fix x64 target platform for appveyor [\#1414](https://github.com/nlohmann/json/pull/1414) ([nickaein](https://github.com/nickaein)) +- Improve dump\_integer performance [\#1411](https://github.com/nlohmann/json/pull/1411) ([nickaein](https://github.com/nickaein)) +- buildsystem: relax requirement on cmake version [\#1409](https://github.com/nlohmann/json/pull/1409) ([yann-morin-1998](https://github.com/yann-morin-1998)) +- CMake: Optional Install if Embedded [\#1330](https://github.com/nlohmann/json/pull/1330) ([ax3l](https://github.com/ax3l)) + +## [v3.5.0](https://github.com/nlohmann/json/releases/tag/v3.5.0) (2018-12-21) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.4.0...v3.5.0) + +- Copyconstructor inserts original into array with single element [\#1397](https://github.com/nlohmann/json/issues/1397) +- Get value without explicit typecasting [\#1395](https://github.com/nlohmann/json/issues/1395) +- Big file parsing [\#1393](https://github.com/nlohmann/json/issues/1393) +- Adding Structured Binding Support [\#1388](https://github.com/nlohmann/json/issues/1388) +- map\ exhibits unexpected behavior [\#1387](https://github.com/nlohmann/json/issues/1387) +- Error Code Return [\#1386](https://github.com/nlohmann/json/issues/1386) +- using unordered\_map as object type [\#1385](https://github.com/nlohmann/json/issues/1385) +- float precision [\#1384](https://github.com/nlohmann/json/issues/1384) +- \[json.exception.type\_error.316\] invalid UTF-8 byte at index 1: 0xC3 [\#1383](https://github.com/nlohmann/json/issues/1383) +- Inconsistent Constructor \(GCC vs. Clang\) [\#1381](https://github.com/nlohmann/json/issues/1381) +- \#define or || [\#1379](https://github.com/nlohmann/json/issues/1379) +- How to iterate inside the values ? [\#1377](https://github.com/nlohmann/json/issues/1377) +- items\(\) unable to get the elements [\#1375](https://github.com/nlohmann/json/issues/1375) +- conversion json to std::map doesn't work for types \ [\#1372](https://github.com/nlohmann/json/issues/1372) +- A minor issue in the build instructions [\#1371](https://github.com/nlohmann/json/issues/1371) +- Using this library without stream ? [\#1370](https://github.com/nlohmann/json/issues/1370) +- Writing and reading BSON data [\#1368](https://github.com/nlohmann/json/issues/1368) +- Retrieving array elements from object type iterator. [\#1367](https://github.com/nlohmann/json/issues/1367) +- json::dump\(\) silently crashes if items contain accented letters [\#1365](https://github.com/nlohmann/json/issues/1365) +- warnings in MSVC \(2015\) in 3.4.0 related to bool... [\#1364](https://github.com/nlohmann/json/issues/1364) +- Cant compile with -C++17 and beyond compiler options [\#1362](https://github.com/nlohmann/json/issues/1362) +- json to concrete type conversion through reference or pointer fails [\#1361](https://github.com/nlohmann/json/issues/1361) +- the first attributes of JSON string is misplaced [\#1360](https://github.com/nlohmann/json/issues/1360) +- Copy-construct using initializer-list converts objects to arrays [\#1359](https://github.com/nlohmann/json/issues/1359) +- About value\(key, default\_value\) and operator\[\]\(key\) [\#1358](https://github.com/nlohmann/json/issues/1358) +- Problem with printing json response object [\#1356](https://github.com/nlohmann/json/issues/1356) +- Serializing pointer segfaults [\#1355](https://github.com/nlohmann/json/issues/1355) +- Read `long long int` data as a number. [\#1354](https://github.com/nlohmann/json/issues/1354) +- eclipse oxygen in ubuntu get\ is ambiguous [\#1353](https://github.com/nlohmann/json/issues/1353) +- Can't build on Visual Studio 2017 v15.8.9 [\#1350](https://github.com/nlohmann/json/issues/1350) +- cannot parse from string? [\#1349](https://github.com/nlohmann/json/issues/1349) +- Error: out\_of\_range [\#1348](https://github.com/nlohmann/json/issues/1348) +- expansion pattern 'CompatibleObjectType' contains no argument packs, with CUDA 10 [\#1347](https://github.com/nlohmann/json/issues/1347) +- Unable to update a value for a nested\(multi-level\) json file [\#1344](https://github.com/nlohmann/json/issues/1344) +- Fails to compile when std::iterator\_traits is not SFINAE friendly. [\#1341](https://github.com/nlohmann/json/issues/1341) +- EOF flag not set on exhausted input streams. [\#1340](https://github.com/nlohmann/json/issues/1340) +- Shadowed Member in merge\_patch [\#1339](https://github.com/nlohmann/json/issues/1339) +- Periods/literal dots in keys? [\#1338](https://github.com/nlohmann/json/issues/1338) +- Protect macro expansion of commonly defined macros [\#1337](https://github.com/nlohmann/json/issues/1337) +- How to validate an input before parsing? [\#1336](https://github.com/nlohmann/json/issues/1336) +- Non-verifying dump\(\) alternative for debugging/logging needed [\#1335](https://github.com/nlohmann/json/issues/1335) +- Json Libarary is not responding for me in c++ [\#1332](https://github.com/nlohmann/json/issues/1332) +- Question - how to find an object in an array [\#1331](https://github.com/nlohmann/json/issues/1331) +- Nesting additional data in json object [\#1328](https://github.com/nlohmann/json/issues/1328) +- can to\_json\(\) be defined inside a class? [\#1324](https://github.com/nlohmann/json/issues/1324) +- CodeBlocks IDE can't find `json.hpp` header [\#1318](https://github.com/nlohmann/json/issues/1318) +- Change json\_pointer to provide an iterator begin/end/etc, don't use vectors, and also enable string\_view [\#1312](https://github.com/nlohmann/json/issues/1312) +- Xcode - adding it to library [\#1300](https://github.com/nlohmann/json/issues/1300) +- unicode: accept char16\_t, char32\_t sequences [\#1298](https://github.com/nlohmann/json/issues/1298) +- unicode: char16\_t\* is compiler error, but char16\_t\[\] is accepted [\#1297](https://github.com/nlohmann/json/issues/1297) +- Dockerfile Project Help Needed [\#1296](https://github.com/nlohmann/json/issues/1296) +- Comparisons between large unsigned and negative signed integers [\#1295](https://github.com/nlohmann/json/issues/1295) +- CMake alias to `nlohmann::json` [\#1291](https://github.com/nlohmann/json/issues/1291) +- Release zips without tests [\#1285](https://github.com/nlohmann/json/issues/1285) +- separate object\_t::key\_type from basic\_json::key\_type, and use an allocator which returns object\_t::key\_type [\#1274](https://github.com/nlohmann/json/issues/1274) +- Is there a nice way to associate external values with json elements? [\#1256](https://github.com/nlohmann/json/issues/1256) +- Delete by json\_pointer [\#1248](https://github.com/nlohmann/json/issues/1248) +- Expose lexer, as a StAX parser [\#1219](https://github.com/nlohmann/json/issues/1219) +- Subclassing json\(\) & error on recursive load [\#1201](https://github.com/nlohmann/json/issues/1201) +- Check value for existence by json\_pointer [\#1194](https://github.com/nlohmann/json/issues/1194) + +- Feature/add file input adapter [\#1392](https://github.com/nlohmann/json/pull/1392) ([dumarjo](https://github.com/dumarjo)) +- Added Support for Structured Bindings [\#1391](https://github.com/nlohmann/json/pull/1391) ([pratikpc](https://github.com/pratikpc)) +- Link to issue \#958 broken [\#1382](https://github.com/nlohmann/json/pull/1382) ([kjpus](https://github.com/kjpus)) +- readme: fix typo [\#1380](https://github.com/nlohmann/json/pull/1380) ([manu-chroma](https://github.com/manu-chroma)) +- recommend using explicit from JSON conversions [\#1363](https://github.com/nlohmann/json/pull/1363) ([theodelrieu](https://github.com/theodelrieu)) +- Fix merge\_patch shadow warning [\#1346](https://github.com/nlohmann/json/pull/1346) ([ax3l](https://github.com/ax3l)) +- Allow installation via Meson [\#1345](https://github.com/nlohmann/json/pull/1345) ([mpoquet](https://github.com/mpoquet)) +- Set eofbit on exhausted input stream. [\#1343](https://github.com/nlohmann/json/pull/1343) ([mefyl](https://github.com/mefyl)) +- Add a SFINAE friendly iterator\_traits and use that instead. [\#1342](https://github.com/nlohmann/json/pull/1342) ([dgavedissian](https://github.com/dgavedissian)) +- Fix EOL Whitespaces & CMake Spelling [\#1329](https://github.com/nlohmann/json/pull/1329) ([ax3l](https://github.com/ax3l)) + +## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0) + +- Big uint64\_t values are serialized wrong [\#1327](https://github.com/nlohmann/json/issues/1327) +- \[Question\] Efficient check for equivalency? [\#1325](https://github.com/nlohmann/json/issues/1325) +- Can't use ifstream and .clear\(\) [\#1321](https://github.com/nlohmann/json/issues/1321) +- \[Warning\] -Wparentheses on line 555 on single\_include [\#1319](https://github.com/nlohmann/json/issues/1319) +- Compilation error using at and find with enum struct [\#1316](https://github.com/nlohmann/json/issues/1316) +- Parsing JSON from a web address [\#1311](https://github.com/nlohmann/json/issues/1311) +- How to convert JSON to Struct with embeded subject [\#1310](https://github.com/nlohmann/json/issues/1310) +- Null safety/coalescing function? [\#1309](https://github.com/nlohmann/json/issues/1309) +- Building fails using single include file: json.hpp [\#1308](https://github.com/nlohmann/json/issues/1308) +- json::parse\(std::string\) Exception inside packaged Lib [\#1306](https://github.com/nlohmann/json/issues/1306) +- Problem in Dockerfile with installation of library [\#1304](https://github.com/nlohmann/json/issues/1304) +- compile error in from\_json converting to container with std::pair [\#1299](https://github.com/nlohmann/json/issues/1299) +- Json that I am trying to parse, and I am lost Structure Array below top level [\#1293](https://github.com/nlohmann/json/issues/1293) +- Serializing std::variant causes stack overflow [\#1292](https://github.com/nlohmann/json/issues/1292) +- How do I go about customising from\_json to support \_\_int128\_t/\_\_uint128\_t? [\#1290](https://github.com/nlohmann/json/issues/1290) +- merge\_patch: inconsistent behaviour merging empty sub-object [\#1289](https://github.com/nlohmann/json/issues/1289) +- Buffer over/underrun using UBJson? [\#1288](https://github.com/nlohmann/json/issues/1288) +- Enable the latest C++ standard with Visual Studio [\#1287](https://github.com/nlohmann/json/issues/1287) +- truncation of constant value in to\_cbor\(\) [\#1286](https://github.com/nlohmann/json/issues/1286) +- eosio.wasmsdk error [\#1284](https://github.com/nlohmann/json/issues/1284) +- use the same interface for writing arrays and non-arrays [\#1283](https://github.com/nlohmann/json/issues/1283) +- How to read json file with optional entries and entries with different types [\#1281](https://github.com/nlohmann/json/issues/1281) +- merge result not as espected [\#1279](https://github.com/nlohmann/json/issues/1279) +- how to get only "name" from below json [\#1278](https://github.com/nlohmann/json/issues/1278) +- syntax error on right json string [\#1276](https://github.com/nlohmann/json/issues/1276) +- Parsing JSON Array where members have no key, using custom types [\#1267](https://github.com/nlohmann/json/issues/1267) +- I get a json exception periodically from json::parse for the same json [\#1263](https://github.com/nlohmann/json/issues/1263) +- GCC 8.2.1. Compilation error: invalid conversion from... [\#1246](https://github.com/nlohmann/json/issues/1246) +- BSON support [\#1244](https://github.com/nlohmann/json/issues/1244) +- enum to json mapping [\#1208](https://github.com/nlohmann/json/issues/1208) +- Soften the landing when dumping non-UTF8 strings \(type\_error.316 exception\) [\#1198](https://github.com/nlohmann/json/issues/1198) + +- Add macro to define enum/JSON mapping [\#1323](https://github.com/nlohmann/json/pull/1323) ([nlohmann](https://github.com/nlohmann)) +- Add BSON support [\#1320](https://github.com/nlohmann/json/pull/1320) ([nlohmann](https://github.com/nlohmann)) +- Properly convert constants to CharType [\#1315](https://github.com/nlohmann/json/pull/1315) ([nlohmann](https://github.com/nlohmann)) +- Allow to set error handler for decoding errors [\#1314](https://github.com/nlohmann/json/pull/1314) ([nlohmann](https://github.com/nlohmann)) +- Add Meson related info to README [\#1305](https://github.com/nlohmann/json/pull/1305) ([koponomarenko](https://github.com/koponomarenko)) +- Improve diagnostic messages for binary formats [\#1303](https://github.com/nlohmann/json/pull/1303) ([nlohmann](https://github.com/nlohmann)) +- add new is\_constructible\_\* traits used in from\_json [\#1301](https://github.com/nlohmann/json/pull/1301) ([theodelrieu](https://github.com/theodelrieu)) +- add constraints for variadic json\_ref constructors [\#1294](https://github.com/nlohmann/json/pull/1294) ([theodelrieu](https://github.com/theodelrieu)) +- Improve diagnostic messages [\#1282](https://github.com/nlohmann/json/pull/1282) ([nlohmann](https://github.com/nlohmann)) +- Removed linter warnings [\#1280](https://github.com/nlohmann/json/pull/1280) ([nlohmann](https://github.com/nlohmann)) +- Thirdparty benchmark: Fix Clang detection. [\#1277](https://github.com/nlohmann/json/pull/1277) ([Lord-Kamina](https://github.com/Lord-Kamina)) + +## [v3.3.0](https://github.com/nlohmann/json/releases/tag/v3.3.0) (2018-10-05) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.3.0...v3.3.0) + +## [3.3.0](https://github.com/nlohmann/json/releases/tag/3.3.0) (2018-10-05) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.2.0...3.3.0) + +- When key is not found print the key name into error too [\#1273](https://github.com/nlohmann/json/issues/1273) +- Visual Studio 2017 15.8.5 "conditional expression is constant" warning on Line 1851 in json.hpp [\#1268](https://github.com/nlohmann/json/issues/1268) +- how can we get this working on WSL? [\#1264](https://github.com/nlohmann/json/issues/1264) +- Help needed [\#1259](https://github.com/nlohmann/json/issues/1259) +- A way to get to a JSON values "key" [\#1258](https://github.com/nlohmann/json/issues/1258) +- While compiling got 76 errors [\#1255](https://github.com/nlohmann/json/issues/1255) +- Two blackslashes on json output file [\#1253](https://github.com/nlohmann/json/issues/1253) +- Including nlohmann the badwrong way. [\#1250](https://github.com/nlohmann/json/issues/1250) +- how to build with clang? [\#1247](https://github.com/nlohmann/json/issues/1247) +- Cmake target\_link\_libraries unable to find nlohmann\_json since version 3.2.0 [\#1243](https://github.com/nlohmann/json/issues/1243) +- \[Question\] Access to end\(\) iterator reference [\#1242](https://github.com/nlohmann/json/issues/1242) +- Parsing different json format [\#1241](https://github.com/nlohmann/json/issues/1241) +- Parsing Multiple JSON Files [\#1240](https://github.com/nlohmann/json/issues/1240) +- Doesn't compile under C++17 [\#1239](https://github.com/nlohmann/json/issues/1239) +- Conversion operator for nlohmann::json is not SFINAE friendly [\#1237](https://github.com/nlohmann/json/issues/1237) +- Custom deserialization of number\_float\_t [\#1236](https://github.com/nlohmann/json/issues/1236) +- deprecated-declarations warnings when compiling tests with GCC 8.2.1. [\#1233](https://github.com/nlohmann/json/issues/1233) +- Incomplete type with json\_fwd.hpp [\#1232](https://github.com/nlohmann/json/issues/1232) +- Parse Error [\#1229](https://github.com/nlohmann/json/issues/1229) +- json::get function with argument [\#1227](https://github.com/nlohmann/json/issues/1227) +- questions regarding from\_json [\#1226](https://github.com/nlohmann/json/issues/1226) +- Lambda in unevaluated context [\#1225](https://github.com/nlohmann/json/issues/1225) +- NLohmann doesn't compile when enabling strict warning policies [\#1224](https://github.com/nlohmann/json/issues/1224) +- Creating array of objects [\#1223](https://github.com/nlohmann/json/issues/1223) +- Somewhat unhelpful error message "cannot use operator\[\] with object" [\#1220](https://github.com/nlohmann/json/issues/1220) +- single\_include json.hpp [\#1218](https://github.com/nlohmann/json/issues/1218) +- Maps with enum class keys which are convertible to JSON strings should be converted to JSON dictionaries [\#1217](https://github.com/nlohmann/json/issues/1217) +- Adding JSON Array to the Array [\#1216](https://github.com/nlohmann/json/issues/1216) +- Best way to output a vector of a given type to json [\#1215](https://github.com/nlohmann/json/issues/1215) +- compiler warning: double definition of macro JSON\_INTERNAL\_CATCH [\#1213](https://github.com/nlohmann/json/issues/1213) +- Compilation error when using MOCK\_METHOD1 from GMock and nlohmann::json [\#1212](https://github.com/nlohmann/json/issues/1212) +- Issues parsing a previously encoded binary \(non-UTF8\) string. [\#1211](https://github.com/nlohmann/json/issues/1211) +- Yet another ordering question: char \* and parse\(\) [\#1209](https://github.com/nlohmann/json/issues/1209) +- Error using gcc 8.1.0 on Ubuntu 14.04 [\#1207](https://github.com/nlohmann/json/issues/1207) +- "type must be string, but is " std::string\(j.type\_name\(\) [\#1206](https://github.com/nlohmann/json/issues/1206) +- Returning empty json object from a function of type const json& ? [\#1205](https://github.com/nlohmann/json/issues/1205) +- VS2017 compiler suggests using constexpr if [\#1204](https://github.com/nlohmann/json/issues/1204) +- Template instatiation error on compiling [\#1203](https://github.com/nlohmann/json/issues/1203) +- BUG - json dump field with unicode -\> array of ints \(instead of string\) [\#1197](https://github.com/nlohmann/json/issues/1197) +- Compile error using Code::Blocks // mingw-w64 GCC 8.1.0 - "Incomplete Type" [\#1193](https://github.com/nlohmann/json/issues/1193) +- SEGFAULT on arm target [\#1190](https://github.com/nlohmann/json/issues/1190) +- Compiler crash with old Clang [\#1179](https://github.com/nlohmann/json/issues/1179) +- Custom Precision on floating point numbers [\#1170](https://github.com/nlohmann/json/issues/1170) +- Can we have a json\_view class like std::string\_view? [\#1158](https://github.com/nlohmann/json/issues/1158) +- improve error handling [\#1152](https://github.com/nlohmann/json/issues/1152) +- We should remove static\_asserts [\#960](https://github.com/nlohmann/json/issues/960) + +- Fix warning C4127: conditional expression is constant [\#1272](https://github.com/nlohmann/json/pull/1272) ([antonioborondo](https://github.com/antonioborondo)) +- Turn off additional deprecation warnings for GCC. [\#1271](https://github.com/nlohmann/json/pull/1271) ([chuckatkins](https://github.com/chuckatkins)) +- docs: Add additional CMake documentation [\#1270](https://github.com/nlohmann/json/pull/1270) ([chuckatkins](https://github.com/chuckatkins)) +- unit-testsuites.cpp: fix hangup if file not found [\#1262](https://github.com/nlohmann/json/pull/1262) ([knilch0r](https://github.com/knilch0r)) +- Fix broken cmake imported target alias [\#1260](https://github.com/nlohmann/json/pull/1260) ([chuckatkins](https://github.com/chuckatkins)) +- GCC 48 [\#1257](https://github.com/nlohmann/json/pull/1257) ([henryiii](https://github.com/henryiii)) +- Add version and license to meson.build [\#1252](https://github.com/nlohmann/json/pull/1252) ([koponomarenko](https://github.com/koponomarenko)) +- \#1179 Reordered the code. It seems to stop clang 3.4.2 in RHEL 7 from crash… [\#1249](https://github.com/nlohmann/json/pull/1249) ([LEgregius](https://github.com/LEgregius)) +- Use a version check to provide backwards comatible CMake imported target names [\#1245](https://github.com/nlohmann/json/pull/1245) ([chuckatkins](https://github.com/chuckatkins)) +- Fix issue \#1237 [\#1238](https://github.com/nlohmann/json/pull/1238) ([theodelrieu](https://github.com/theodelrieu)) +- Add a get overload taking a parameter. [\#1231](https://github.com/nlohmann/json/pull/1231) ([theodelrieu](https://github.com/theodelrieu)) +- Move lambda out of unevaluated context [\#1230](https://github.com/nlohmann/json/pull/1230) ([mandreyel](https://github.com/mandreyel)) +- Remove static asserts [\#1228](https://github.com/nlohmann/json/pull/1228) ([theodelrieu](https://github.com/theodelrieu)) +- Better error 305 [\#1221](https://github.com/nlohmann/json/pull/1221) ([rivertam](https://github.com/rivertam)) +- Fix \#1213 [\#1214](https://github.com/nlohmann/json/pull/1214) ([simnalamburt](https://github.com/simnalamburt)) +- Export package to allow builds without installing [\#1202](https://github.com/nlohmann/json/pull/1202) ([dennisfischer](https://github.com/dennisfischer)) + +## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-20) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.2.0...v3.2.0) + +## [3.2.0](https://github.com/nlohmann/json/releases/tag/3.2.0) (2018-08-20) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...3.2.0) + +- Am I doing this wrong? Getting an empty string [\#1199](https://github.com/nlohmann/json/issues/1199) +- Incompatible Pointer Type [\#1196](https://github.com/nlohmann/json/issues/1196) +- json.exception.type\_error.316 [\#1195](https://github.com/nlohmann/json/issues/1195) +- Strange warnings in Code::Blocks 17.12, GNU GCC [\#1192](https://github.com/nlohmann/json/issues/1192) +- \[Question\] Current place in code to change floating point resolution [\#1191](https://github.com/nlohmann/json/issues/1191) +- Add key name when throwing type error [\#1189](https://github.com/nlohmann/json/issues/1189) +- Not able to include in visual studio code? [\#1188](https://github.com/nlohmann/json/issues/1188) +- Get an Index or row number of an element [\#1186](https://github.com/nlohmann/json/issues/1186) +- Difference between `merge_patch` and `update` [\#1183](https://github.com/nlohmann/json/issues/1183) +- Is there a way to get an element from a JSON without throwing an exception on failure? [\#1182](https://github.com/nlohmann/json/issues/1182) +- to\_string? [\#1181](https://github.com/nlohmann/json/issues/1181) +- How to cache a json object's pointer into a map? [\#1180](https://github.com/nlohmann/json/issues/1180) +- Can this library work within a Qt project for Android using Qt Creator? [\#1178](https://github.com/nlohmann/json/issues/1178) +- How to get all keys of one object? [\#1177](https://github.com/nlohmann/json/issues/1177) +- How can I only parse the first level and get the value as string? [\#1175](https://github.com/nlohmann/json/issues/1175) +- I have a query regarding nlohmann::basic\_json::basic\_json [\#1174](https://github.com/nlohmann/json/issues/1174) +- unordered\_map with vectors won't convert to json? [\#1173](https://github.com/nlohmann/json/issues/1173) +- return json objects from functions [\#1172](https://github.com/nlohmann/json/issues/1172) +- Problem when exporting to CBOR [\#1171](https://github.com/nlohmann/json/issues/1171) +- Roundtripping null to nullptr does not work [\#1169](https://github.com/nlohmann/json/issues/1169) +- MSVC fails to compile std::swap specialization for nlohmann::json [\#1168](https://github.com/nlohmann/json/issues/1168) +- Unexpected behaviour of is\_null - Part II [\#1167](https://github.com/nlohmann/json/issues/1167) +- Floating point imprecision [\#1166](https://github.com/nlohmann/json/issues/1166) +- Combine json objects into one? [\#1165](https://github.com/nlohmann/json/issues/1165) +- Is there any way to know if the object has changed? [\#1164](https://github.com/nlohmann/json/issues/1164) +- Value throws on null string [\#1163](https://github.com/nlohmann/json/issues/1163) +- Weird template issue in large project [\#1162](https://github.com/nlohmann/json/issues/1162) +- \_json returns a different result vs ::parse [\#1161](https://github.com/nlohmann/json/issues/1161) +- Showing difference between two json objects [\#1160](https://github.com/nlohmann/json/issues/1160) +- no instance of overloaded function "std::swap" matches the specified type [\#1159](https://github.com/nlohmann/json/issues/1159) +- resize\(...\)? [\#1157](https://github.com/nlohmann/json/issues/1157) +- Issue with struct nested in class' to\_json [\#1155](https://github.com/nlohmann/json/issues/1155) +- Deserialize std::map with std::nan [\#1154](https://github.com/nlohmann/json/issues/1154) +- Parse throwing errors [\#1149](https://github.com/nlohmann/json/issues/1149) +- cocoapod integration [\#1148](https://github.com/nlohmann/json/issues/1148) +- wstring parsing [\#1147](https://github.com/nlohmann/json/issues/1147) +- Is it possible to dump a two-dimensional array to "\[\[null\],\[1,2,3\]\]"? [\#1146](https://github.com/nlohmann/json/issues/1146) +- Want to write a class member variable and a struct variable \( this structure is inside the class\) to the json file [\#1145](https://github.com/nlohmann/json/issues/1145) +- Does json support converting an instance of a struct into json string? [\#1143](https://github.com/nlohmann/json/issues/1143) +- \#Most efficient way to search for child parameters \(recursive find?\) [\#1141](https://github.com/nlohmann/json/issues/1141) +- could not find to\_json\(\) method in T's namespace [\#1140](https://github.com/nlohmann/json/issues/1140) +- chars get treated as JSON numbers not JSON strings [\#1139](https://github.com/nlohmann/json/issues/1139) +- How do I count number of objects in array? [\#1137](https://github.com/nlohmann/json/issues/1137) +- Serializing a vector of classes? [\#1136](https://github.com/nlohmann/json/issues/1136) +- Compile error. Unable convert form nullptr to nullptr&& [\#1135](https://github.com/nlohmann/json/issues/1135) +- std::unordered\_map in struct, serialization [\#1133](https://github.com/nlohmann/json/issues/1133) +- dump\(\) can't handle umlauts [\#1131](https://github.com/nlohmann/json/issues/1131) +- Add a way to get a key reference from the iterator [\#1127](https://github.com/nlohmann/json/issues/1127) +- can't not parse "\\“ string [\#1123](https://github.com/nlohmann/json/issues/1123) +- if json file contain Internationalization chars , get exception [\#1122](https://github.com/nlohmann/json/issues/1122) +- How to use a json::iterator dereferenced value in code? [\#1120](https://github.com/nlohmann/json/issues/1120) +- Disable implicit conversions from json to std::initializer\_list\ for any T [\#1118](https://github.com/nlohmann/json/issues/1118) +- Implicit conversions to complex types can lead to surprising and confusing errors [\#1116](https://github.com/nlohmann/json/issues/1116) +- How can I write from\_json for a complex datatype that is not default constructible? [\#1115](https://github.com/nlohmann/json/issues/1115) +- Compile error in VS2015 when compiling unit-conversions.cpp [\#1114](https://github.com/nlohmann/json/issues/1114) +- ADL Serializer for std::any / boost::any [\#1113](https://github.com/nlohmann/json/issues/1113) +- Unexpected behaviour of is\_null [\#1112](https://github.com/nlohmann/json/issues/1112) +- How to resolve " undefined reference to `std::\_\_throw\_bad\_cast\(\)'" [\#1111](https://github.com/nlohmann/json/issues/1111) +- cannot compile on ubuntu 18.04 and 16.04 [\#1110](https://github.com/nlohmann/json/issues/1110) +- JSON representation for floating point values has too many digits [\#1109](https://github.com/nlohmann/json/issues/1109) +- Not working for classes containing "\_declspec\(dllimport\)" in their declaration [\#1108](https://github.com/nlohmann/json/issues/1108) +- Get keys from json object [\#1107](https://github.com/nlohmann/json/issues/1107) +- Cannot deserialize types using std::ratio [\#1105](https://github.com/nlohmann/json/issues/1105) +- i want to learn json [\#1104](https://github.com/nlohmann/json/issues/1104) +- Type checking during compile [\#1103](https://github.com/nlohmann/json/issues/1103) +- Iterate through sub items [\#1102](https://github.com/nlohmann/json/issues/1102) +- cppcheck failing for version 3.1.2 [\#1101](https://github.com/nlohmann/json/issues/1101) +- Deserializing std::map [\#1100](https://github.com/nlohmann/json/issues/1100) +- accessing key by reference [\#1098](https://github.com/nlohmann/json/issues/1098) +- clang 3.8.0 croaks while trying to compile with debug symbols [\#1097](https://github.com/nlohmann/json/issues/1097) +- Serialize a list of class objects with json [\#1096](https://github.com/nlohmann/json/issues/1096) +- Small question [\#1094](https://github.com/nlohmann/json/issues/1094) +- Upgrading to 3.x: to\_/from\_json with enum class [\#1093](https://github.com/nlohmann/json/issues/1093) +- Q: few questions about json construction [\#1092](https://github.com/nlohmann/json/issues/1092) +- general crayCC compilation failure [\#1091](https://github.com/nlohmann/json/issues/1091) +- Merge Patch clears original data [\#1090](https://github.com/nlohmann/json/issues/1090) +- \[Question\] how to use nlohmann/json in c++? [\#1088](https://github.com/nlohmann/json/issues/1088) +- C++17 decomposition declaration support [\#1087](https://github.com/nlohmann/json/issues/1087) +- \[Question\] Access multi-level json objects [\#1086](https://github.com/nlohmann/json/issues/1086) +- Serializing vector [\#1085](https://github.com/nlohmann/json/issues/1085) +- update nested value in multi hierarchy json object [\#1084](https://github.com/nlohmann/json/issues/1084) +- Overriding default values? [\#1083](https://github.com/nlohmann/json/issues/1083) +- detail namespace collision with Cereal? [\#1082](https://github.com/nlohmann/json/issues/1082) +- Error using json.dump\(\); [\#1081](https://github.com/nlohmann/json/issues/1081) +- Consuming TCP Stream [\#1080](https://github.com/nlohmann/json/issues/1080) +- Compilation error with strong typed enums in map in combination with namespaces [\#1079](https://github.com/nlohmann/json/issues/1079) +- cassert error [\#1076](https://github.com/nlohmann/json/issues/1076) +- Valid json data not being parsed [\#1075](https://github.com/nlohmann/json/issues/1075) +- Feature request :: Better testing for key existance without try/catch [\#1074](https://github.com/nlohmann/json/issues/1074) +- Hi, I have input like a.b.c and want to convert it to \"a\"{\"b\": \"c\"} form. Any suggestions how do I do this? Thanks. [\#1073](https://github.com/nlohmann/json/issues/1073) +- ADL deserializer not picked up for non default-constructible type [\#1072](https://github.com/nlohmann/json/issues/1072) +- Deserializing std::array doesn't compiler \(no insert\(\)\) [\#1071](https://github.com/nlohmann/json/issues/1071) +- Serializing OpenCV Mat problem [\#1070](https://github.com/nlohmann/json/issues/1070) +- Compilation error with ICPC compiler [\#1068](https://github.com/nlohmann/json/issues/1068) +- Not existing value, crash [\#1065](https://github.com/nlohmann/json/issues/1065) +- cyryllic symbols [\#1064](https://github.com/nlohmann/json/issues/1064) +- newbie usage question [\#1063](https://github.com/nlohmann/json/issues/1063) +- Trying j\["strTest"\] = "%A" produces "strTest": "-0X1.CCCCCCCCCCCCCP+205" [\#1062](https://github.com/nlohmann/json/issues/1062) +- convert json value to std::string??? [\#1061](https://github.com/nlohmann/json/issues/1061) +- Commented out test cases, should they be removed? [\#1060](https://github.com/nlohmann/json/issues/1060) +- different behaviour between clang and gcc with braced initialization [\#1059](https://github.com/nlohmann/json/issues/1059) +- json array: initialize with prescribed size and `resize` method. [\#1057](https://github.com/nlohmann/json/issues/1057) +- Is it possible to use exceptions istead of assertions? [\#1056](https://github.com/nlohmann/json/issues/1056) +- when using assign operator in with json object a static assertion fails.. [\#1055](https://github.com/nlohmann/json/issues/1055) +- Iterate over leafs of a JSON data structure: enrich the JSON pointer API [\#1054](https://github.com/nlohmann/json/issues/1054) +- \[Feature request\] Access by path [\#1053](https://github.com/nlohmann/json/issues/1053) +- document that implicit js -\> primitive conversion does not work for std::string::value\_type and why [\#1052](https://github.com/nlohmann/json/issues/1052) +- error: ‘BasicJsonType’ in namespace ‘::’ does not name a type [\#1051](https://github.com/nlohmann/json/issues/1051) +- Destructor is called when filling object through assignement [\#1050](https://github.com/nlohmann/json/issues/1050) +- Is this thing thread safe for reads? [\#1049](https://github.com/nlohmann/json/issues/1049) +- clang-tidy: Call to virtual function during construction [\#1046](https://github.com/nlohmann/json/issues/1046) +- Using STL algorithms with JSON containers with expected results? [\#1045](https://github.com/nlohmann/json/issues/1045) +- Usage with gtest/gmock not working as expected [\#1044](https://github.com/nlohmann/json/issues/1044) +- Consequences of from\_json / to\_json being in namespace of data struct. [\#1042](https://github.com/nlohmann/json/issues/1042) +- const\_reference operator\[\]\(const typename object\_t::key\_type& key\) const throw instead of assert [\#1039](https://github.com/nlohmann/json/issues/1039) +- Trying to retrieve data from nested objects [\#1038](https://github.com/nlohmann/json/issues/1038) +- Direct download link for json\_fwd.hpp? [\#1037](https://github.com/nlohmann/json/issues/1037) +- I know the library supports UTF-8, but failed to dump the value [\#1036](https://github.com/nlohmann/json/issues/1036) +- Putting a Vec3-like vector into a json object [\#1035](https://github.com/nlohmann/json/issues/1035) +- Ternary operator crash [\#1034](https://github.com/nlohmann/json/issues/1034) +- Issued with Clion Inspection Resolution since 2018.1 [\#1033](https://github.com/nlohmann/json/issues/1033) +- Some testcases fail and one never finishes [\#1032](https://github.com/nlohmann/json/issues/1032) +- Can this class work with wchar\_t / std::wstring? [\#1031](https://github.com/nlohmann/json/issues/1031) +- Makefile: Valgrind flags have no effect [\#1030](https://github.com/nlohmann/json/issues/1030) +- 「==」 Should be 「\>」 [\#1029](https://github.com/nlohmann/json/issues/1029) +- HOCON reader? [\#1027](https://github.com/nlohmann/json/issues/1027) +- add json string in previous string?? [\#1025](https://github.com/nlohmann/json/issues/1025) +- RFC: fluent parsing interface [\#1023](https://github.com/nlohmann/json/issues/1023) +- Does it support chinese character? [\#1022](https://github.com/nlohmann/json/issues/1022) +- to/from\_msgpack only works with standard typization [\#1021](https://github.com/nlohmann/json/issues/1021) +- Build failure using latest clang and GCC compilers [\#1020](https://github.com/nlohmann/json/issues/1020) +- can two json objects be concatenated? [\#1019](https://github.com/nlohmann/json/issues/1019) +- Erase by integer index [\#1018](https://github.com/nlohmann/json/issues/1018) +- Function find overload taking a json\_pointer [\#1017](https://github.com/nlohmann/json/issues/1017) +- I think should implement an parser function [\#1016](https://github.com/nlohmann/json/issues/1016) +- Readme gif [\#1015](https://github.com/nlohmann/json/issues/1015) +- Python bindings [\#1014](https://github.com/nlohmann/json/issues/1014) +- how to add two json string in single object?? [\#1012](https://github.com/nlohmann/json/issues/1012) +- how to serialize class Object \(convert data in object into json\)?? [\#1011](https://github.com/nlohmann/json/issues/1011) +- Enable forward declaration of json by making json a class instead of a using declaration [\#997](https://github.com/nlohmann/json/issues/997) +- compilation error while using intel c++ compiler 2018 [\#994](https://github.com/nlohmann/json/issues/994) +- How to create a json variable? [\#990](https://github.com/nlohmann/json/issues/990) +- istream \>\> json --- 1st character skipped in stream [\#976](https://github.com/nlohmann/json/issues/976) +- Add a SAX parser [\#971](https://github.com/nlohmann/json/issues/971) +- How to solve large json file? [\#927](https://github.com/nlohmann/json/issues/927) +- json\_pointer public push\_back, pop\_back [\#837](https://github.com/nlohmann/json/issues/837) +- Using input\_adapter in a slightly unexpected way [\#834](https://github.com/nlohmann/json/issues/834) + +- Fix -Wno-sometimes-uninitialized by initializing "result" in parse\_sax [\#1200](https://github.com/nlohmann/json/pull/1200) ([thyu](https://github.com/thyu)) +- \[RFC\] Introduce a new macro function: JSON\_INTERNAL\_CATCH [\#1187](https://github.com/nlohmann/json/pull/1187) ([simnalamburt](https://github.com/simnalamburt)) +- Fix unit tests that were silently skipped or crashed \(depending on the compiler\) [\#1176](https://github.com/nlohmann/json/pull/1176) ([grembo](https://github.com/grembo)) +- Refactor/no virtual sax [\#1153](https://github.com/nlohmann/json/pull/1153) ([theodelrieu](https://github.com/theodelrieu)) +- Fixed compiler error in VS 2015 for debug mode [\#1151](https://github.com/nlohmann/json/pull/1151) ([sonulohani](https://github.com/sonulohani)) +- Fix links to cppreference named requirements \(formerly concepts\) [\#1144](https://github.com/nlohmann/json/pull/1144) ([jrakow](https://github.com/jrakow)) +- meson: fix include directory [\#1142](https://github.com/nlohmann/json/pull/1142) ([jrakow](https://github.com/jrakow)) +- Feature/unordered map conversion [\#1138](https://github.com/nlohmann/json/pull/1138) ([theodelrieu](https://github.com/theodelrieu)) +- fixed compile error for \#1045 [\#1134](https://github.com/nlohmann/json/pull/1134) ([Daniel599](https://github.com/Daniel599)) +- test \(non\)equality for alt\_string implementation [\#1130](https://github.com/nlohmann/json/pull/1130) ([agrianius](https://github.com/agrianius)) +- remove stringstream dependency [\#1117](https://github.com/nlohmann/json/pull/1117) ([TinyTinni](https://github.com/TinyTinni)) +- Provide a from\_json overload for std::map [\#1089](https://github.com/nlohmann/json/pull/1089) ([theodelrieu](https://github.com/theodelrieu)) +- fix typo in README [\#1078](https://github.com/nlohmann/json/pull/1078) ([martin-mfg](https://github.com/martin-mfg)) +- Fix typo [\#1058](https://github.com/nlohmann/json/pull/1058) ([dns13](https://github.com/dns13)) +- Misc cmake packaging enhancements [\#1048](https://github.com/nlohmann/json/pull/1048) ([chuckatkins](https://github.com/chuckatkins)) +- Fixed incorrect LLVM version number in README [\#1047](https://github.com/nlohmann/json/pull/1047) ([jammehcow](https://github.com/jammehcow)) +- Fix trivial typo in comment. [\#1043](https://github.com/nlohmann/json/pull/1043) ([coryan](https://github.com/coryan)) +- Package Manager: Spack [\#1041](https://github.com/nlohmann/json/pull/1041) ([ax3l](https://github.com/ax3l)) +- CMake: 3.8+ is Sufficient [\#1040](https://github.com/nlohmann/json/pull/1040) ([ax3l](https://github.com/ax3l)) +- Added support for string\_view in C++17 [\#1028](https://github.com/nlohmann/json/pull/1028) ([gracicot](https://github.com/gracicot)) +- Added public target\_compile\_features for auto and constexpr [\#1026](https://github.com/nlohmann/json/pull/1026) ([ktonon](https://github.com/ktonon)) + +## [v3.1.2](https://github.com/nlohmann/json/releases/tag/v3.1.2) (2018-03-14) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.1.2...v3.1.2) + +## [3.1.2](https://github.com/nlohmann/json/releases/tag/3.1.2) (2018-03-14) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.1...3.1.2) + +- STL containers are always serialized to a nested array like \[\[1,2,3\]\] [\#1013](https://github.com/nlohmann/json/issues/1013) +- The library doesn't want to insert an unordered\_map [\#1010](https://github.com/nlohmann/json/issues/1010) +- Convert Json to uint8\_t [\#1008](https://github.com/nlohmann/json/issues/1008) +- How to compare two JSON objects? [\#1007](https://github.com/nlohmann/json/issues/1007) +- Syntax checking [\#1003](https://github.com/nlohmann/json/issues/1003) +- more than one operator '=' matches these operands [\#1002](https://github.com/nlohmann/json/issues/1002) +- How to check if key existed [\#1000](https://github.com/nlohmann/json/issues/1000) +- nlohmann::json::parse exhaust memory in go binding [\#999](https://github.com/nlohmann/json/issues/999) +- Range-based iteration over a non-array object [\#998](https://github.com/nlohmann/json/issues/998) +- get\ for types that are not default constructible [\#996](https://github.com/nlohmann/json/issues/996) +- Prevent Null values to appear in .dump\(\) [\#995](https://github.com/nlohmann/json/issues/995) +- number parsing [\#993](https://github.com/nlohmann/json/issues/993) +- C2664 \(C++/CLR\) cannot convert 'nullptr' to 'nullptr &&' [\#987](https://github.com/nlohmann/json/issues/987) +- Uniform initialization from another json object differs between gcc and clang. [\#985](https://github.com/nlohmann/json/issues/985) +- Problem with adding the lib as a submodule [\#983](https://github.com/nlohmann/json/issues/983) +- UTF-8/Unicode error [\#982](https://github.com/nlohmann/json/issues/982) +- "forcing MSVC stacktrace to show which T we're talking about." error [\#980](https://github.com/nlohmann/json/issues/980) +- reverse order of serialization [\#979](https://github.com/nlohmann/json/issues/979) +- Assigning between different json types [\#977](https://github.com/nlohmann/json/issues/977) +- Support serialisation of `unique_ptr<>` and `shared_ptr<>` [\#975](https://github.com/nlohmann/json/issues/975) +- Unexpected end of input \(not same as one before\) [\#974](https://github.com/nlohmann/json/issues/974) +- Segfault on direct initializing json object [\#973](https://github.com/nlohmann/json/issues/973) +- Segmentation fault on G++ when trying to assign json string literal to custom json type. [\#972](https://github.com/nlohmann/json/issues/972) +- os\_defines.h:44:19: error: missing binary operator before token "\(" [\#970](https://github.com/nlohmann/json/issues/970) +- Passing an iteration object by reference to a function [\#967](https://github.com/nlohmann/json/issues/967) +- Json and fmt::lib's format\_arg\(\) [\#964](https://github.com/nlohmann/json/issues/964) + +- Allowing for user-defined string type in lexer/parser [\#1009](https://github.com/nlohmann/json/pull/1009) ([nlohmann](https://github.com/nlohmann)) +- dump to alternative string type, as defined in basic\_json template [\#1006](https://github.com/nlohmann/json/pull/1006) ([agrianius](https://github.com/agrianius)) +- Fix memory leak during parser callback [\#1001](https://github.com/nlohmann/json/pull/1001) ([nlohmann](https://github.com/nlohmann)) +- fixed misprinted condition detected by PVS Studio. [\#992](https://github.com/nlohmann/json/pull/992) ([bogemic](https://github.com/bogemic)) +- Fix/basic json conversion [\#986](https://github.com/nlohmann/json/pull/986) ([theodelrieu](https://github.com/theodelrieu)) +- Make integration section concise [\#981](https://github.com/nlohmann/json/pull/981) ([wla80](https://github.com/wla80)) + +## [v3.1.1](https://github.com/nlohmann/json/releases/tag/v3.1.1) (2018-02-13) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.0...v3.1.1) + +- Updation of child object isn't reflected in parent Object [\#968](https://github.com/nlohmann/json/issues/968) +- How to add user defined C++ path to sublime text [\#966](https://github.com/nlohmann/json/issues/966) +- fast number parsing [\#965](https://github.com/nlohmann/json/issues/965) +- With non-unique keys, later stored entries are not taken into account anymore [\#963](https://github.com/nlohmann/json/issues/963) +- Timeout \(OSS-Fuzz 6034\) [\#962](https://github.com/nlohmann/json/issues/962) +- Incorrect parsing of indefinite length CBOR strings. [\#961](https://github.com/nlohmann/json/issues/961) +- Reload a json file at runtime without emptying my std::ifstream [\#959](https://github.com/nlohmann/json/issues/959) +- Split headers should be part of the release [\#956](https://github.com/nlohmann/json/issues/956) +- Coveralls shows no coverage data [\#953](https://github.com/nlohmann/json/issues/953) +- Feature request: Implicit conversion to bool [\#951](https://github.com/nlohmann/json/issues/951) +- converting json to vector of type with templated constructor [\#924](https://github.com/nlohmann/json/issues/924) +- No structured bindings support? [\#901](https://github.com/nlohmann/json/issues/901) +- \[Request\] Macro generating from\_json\(\) and to\_json\(\) [\#895](https://github.com/nlohmann/json/issues/895) +- basic\_json::value throws exception instead of returning default value [\#871](https://github.com/nlohmann/json/issues/871) + +- Fix constraints on from\_json\(CompatibleArrayType\) [\#969](https://github.com/nlohmann/json/pull/969) ([theodelrieu](https://github.com/theodelrieu)) +- Make coveralls watch the include folder [\#957](https://github.com/nlohmann/json/pull/957) ([theodelrieu](https://github.com/theodelrieu)) +- Fix links in README.md [\#955](https://github.com/nlohmann/json/pull/955) ([patrikhuber](https://github.com/patrikhuber)) +- Add a note about installing the library with cget [\#954](https://github.com/nlohmann/json/pull/954) ([pfultz2](https://github.com/pfultz2)) + +## [v3.1.0](https://github.com/nlohmann/json/releases/tag/v3.1.0) (2018-02-01) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.1.0...v3.1.0) + +## [3.1.0](https://github.com/nlohmann/json/releases/tag/3.1.0) (2018-02-01) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.1...3.1.0) + +- I have a proposal [\#949](https://github.com/nlohmann/json/issues/949) +- VERSION define\(s\) [\#948](https://github.com/nlohmann/json/issues/948) +- v3.0.1 compile error in icc 16.0.4 [\#947](https://github.com/nlohmann/json/issues/947) +- Use in VS2017 15.5.5 [\#946](https://github.com/nlohmann/json/issues/946) +- Process for reporting Security Bugs? [\#945](https://github.com/nlohmann/json/issues/945) +- Please expose a NLOHMANN\_JSON\_VERSION macro [\#943](https://github.com/nlohmann/json/issues/943) +- Change header include directory to nlohmann/json [\#942](https://github.com/nlohmann/json/issues/942) +- string\_type in binary\_reader [\#941](https://github.com/nlohmann/json/issues/941) +- compile error with clang 5.0 -std=c++1z and no string\_view [\#939](https://github.com/nlohmann/json/issues/939) +- Allow overriding JSON\_THROW to something else than abort\(\) [\#938](https://github.com/nlohmann/json/issues/938) +- Handle invalid string in Json file [\#937](https://github.com/nlohmann/json/issues/937) +- Unused variable 'kMinExp' [\#935](https://github.com/nlohmann/json/issues/935) +- yytext is already defined [\#933](https://github.com/nlohmann/json/issues/933) +- Equality operator fails [\#931](https://github.com/nlohmann/json/issues/931) +- use in visual studio 2015 [\#929](https://github.com/nlohmann/json/issues/929) +- Relative includes of json\_fwd.hpp in detail/meta.hpp. \[Develop branch\] [\#928](https://github.com/nlohmann/json/issues/928) +- GCC 7.x issue [\#926](https://github.com/nlohmann/json/issues/926) +- json\_fwd.hpp not installed [\#923](https://github.com/nlohmann/json/issues/923) +- Use Google Benchmarks [\#921](https://github.com/nlohmann/json/issues/921) +- Move class json\_pointer to separate file [\#920](https://github.com/nlohmann/json/issues/920) +- Unable to locate 'to\_json\(\)' and 'from\_json\(\)' methods in the same namespace [\#917](https://github.com/nlohmann/json/issues/917) +- \[answered\]Read key1 from .value example [\#914](https://github.com/nlohmann/json/issues/914) +- Don't use `define private public` in test files [\#913](https://github.com/nlohmann/json/issues/913) +- value\(\) template argument type deduction [\#912](https://github.com/nlohmann/json/issues/912) +- Installation path is incorrect [\#910](https://github.com/nlohmann/json/issues/910) +- H [\#909](https://github.com/nlohmann/json/issues/909) +- Build failure using clang 5 [\#908](https://github.com/nlohmann/json/issues/908) +- Amalgate [\#907](https://github.com/nlohmann/json/issues/907) +- Update documentation and tests wrt. split headers [\#906](https://github.com/nlohmann/json/issues/906) +- Lib not working on ubuntu 16.04 [\#905](https://github.com/nlohmann/json/issues/905) +- Problem when writing to file. [\#904](https://github.com/nlohmann/json/issues/904) +- C2864 error when compiling with VS2015 and VS 2017 [\#903](https://github.com/nlohmann/json/issues/903) +- \[json.exception.type\_error.304\] cannot use at\(\) with object [\#902](https://github.com/nlohmann/json/issues/902) +- How do I forward nlohmann::json declaration? [\#899](https://github.com/nlohmann/json/issues/899) +- How to effectively store binary data? [\#898](https://github.com/nlohmann/json/issues/898) +- How to get the length of a JSON string without retrieving its std::string? [\#897](https://github.com/nlohmann/json/issues/897) +- Regression Tests Failure using "ctest" [\#887](https://github.com/nlohmann/json/issues/887) +- Discuss: add JSON Merge Patch \(RFC 7396\)? [\#877](https://github.com/nlohmann/json/issues/877) +- Discuss: replace static "iterator\_wrapper" function with "items" member function [\#874](https://github.com/nlohmann/json/issues/874) +- Make optional user-data available in from\_json [\#864](https://github.com/nlohmann/json/issues/864) +- Casting to std::string not working in VS2015 [\#861](https://github.com/nlohmann/json/issues/861) +- Sequential reading of JSON arrays [\#851](https://github.com/nlohmann/json/issues/851) +- Idea: Handle Multimaps Better [\#816](https://github.com/nlohmann/json/issues/816) +- Floating point rounding [\#777](https://github.com/nlohmann/json/issues/777) +- Loss of precision when serializing \ [\#360](https://github.com/nlohmann/json/issues/360) + +- Templatize std::string in binary\_reader \#941 [\#950](https://github.com/nlohmann/json/pull/950) ([kaidokert](https://github.com/kaidokert)) +- fix cmake install directory \(for real this time\) [\#944](https://github.com/nlohmann/json/pull/944) ([theodelrieu](https://github.com/theodelrieu)) +- Allow overriding THROW/CATCH/TRY macros with no-exceptions \#938 [\#940](https://github.com/nlohmann/json/pull/940) ([kaidokert](https://github.com/kaidokert)) +- Removed compiler warning about unused variable 'kMinExp' [\#936](https://github.com/nlohmann/json/pull/936) ([zerodefect](https://github.com/zerodefect)) +- Fix a typo in README.md [\#930](https://github.com/nlohmann/json/pull/930) ([Pipeliner](https://github.com/Pipeliner)) +- Howto installation of json\_fwd.hpp \(fixes \#923\) [\#925](https://github.com/nlohmann/json/pull/925) ([zerodefect](https://github.com/zerodefect)) +- fix sfinae on basic\_json UDT constructor [\#919](https://github.com/nlohmann/json/pull/919) ([theodelrieu](https://github.com/theodelrieu)) +- Floating-point formatting [\#915](https://github.com/nlohmann/json/pull/915) ([abolz](https://github.com/abolz)) +- Fix/cmake install [\#911](https://github.com/nlohmann/json/pull/911) ([theodelrieu](https://github.com/theodelrieu)) +- fix link to the documentation of the emplace function [\#900](https://github.com/nlohmann/json/pull/900) ([Dobiasd](https://github.com/Dobiasd)) +- JSON Merge Patch \(RFC 7396\) [\#876](https://github.com/nlohmann/json/pull/876) ([nlohmann](https://github.com/nlohmann)) +- Refactor/split it [\#700](https://github.com/nlohmann/json/pull/700) ([theodelrieu](https://github.com/theodelrieu)) + +## [v3.0.1](https://github.com/nlohmann/json/releases/tag/v3.0.1) (2017-12-29) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.0.1...v3.0.1) + +## [3.0.1](https://github.com/nlohmann/json/releases/tag/3.0.1) (2017-12-29) + +[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.0...3.0.1) + +- Problem parsing array to global vector [\#896](https://github.com/nlohmann/json/issues/896) +- Invalid RFC6902 copy operation succeeds [\#894](https://github.com/nlohmann/json/issues/894) +- How to rename a key during looping? [\#893](https://github.com/nlohmann/json/issues/893) +- clang++-6.0 \(6.0.0-svn321357-1\) warning [\#892](https://github.com/nlohmann/json/issues/892) +- Make json.hpp aware of the modules TS? [\#891](https://github.com/nlohmann/json/issues/891) +- All enum values not handled in switch cases. \( -Wswitch-enum \) [\#889](https://github.com/nlohmann/json/issues/889) +- JSON Pointer resolve failure resulting in incorrect exception code [\#888](https://github.com/nlohmann/json/issues/888) +- Unexpected nested arrays from std::vector [\#886](https://github.com/nlohmann/json/issues/886) +- erase multiple elements from a json object [\#884](https://github.com/nlohmann/json/issues/884) +- Container function overview in Doxygen is not updated [\#883](https://github.com/nlohmann/json/issues/883) +- How to use this for binary file uploads [\#881](https://github.com/nlohmann/json/issues/881) +- Allow setting JSON\_BuildTests=OFF from parent CMakeLists.txt [\#846](https://github.com/nlohmann/json/issues/846) +- Unit test fails for local-independent str-to-num [\#845](https://github.com/nlohmann/json/issues/845) +- Another idea about type support [\#774](https://github.com/nlohmann/json/issues/774) + +- Includes CTest module/adds BUILD\_TESTING option [\#885](https://github.com/nlohmann/json/pull/885) ([TinyTinni](https://github.com/TinyTinni)) +- Fix MSVC warning C4819 [\#882](https://github.com/nlohmann/json/pull/882) ([erengy](https://github.com/erengy)) +- Merge branch 'develop' into coverity\_scan [\#880](https://github.com/nlohmann/json/pull/880) ([nlohmann](https://github.com/nlohmann)) +- :wrench: Fix up a few more effc++ items [\#858](https://github.com/nlohmann/json/pull/858) ([mattismyname](https://github.com/mattismyname)) + +## [v3.0.0](https://github.com/nlohmann/json/releases/tag/v3.0.0) (2017-12-17) + +[Full Changelog](https://github.com/nlohmann/json/compare/3.0.0...v3.0.0) + +## [3.0.0](https://github.com/nlohmann/json/releases/tag/3.0.0) (2017-12-17) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.1...3.0.0) + +- unicode strings [\#878](https://github.com/nlohmann/json/issues/878) +- Visual Studio 2017 15.5 C++17 std::allocator deprecations [\#872](https://github.com/nlohmann/json/issues/872) +- Typo "excpetion" [\#869](https://github.com/nlohmann/json/issues/869) +- Explicit array example in README.md incorrect [\#867](https://github.com/nlohmann/json/issues/867) +- why don't you release this from Feb. ? [\#865](https://github.com/nlohmann/json/issues/865) +- json::parse throws std::invalid\_argument when processing string generated by json::dump\(\) [\#863](https://github.com/nlohmann/json/issues/863) +- code analysis: potential bug? [\#859](https://github.com/nlohmann/json/issues/859) +- MSVC2017, 15.5 new issues. [\#857](https://github.com/nlohmann/json/issues/857) +- very basic: fetching string value/content without quotes [\#853](https://github.com/nlohmann/json/issues/853) +- Ambiguous function call to get with pointer type and constant json object in VS2015 \(15.4.4\) [\#852](https://github.com/nlohmann/json/issues/852) +- How to put object in the array as a member? [\#850](https://github.com/nlohmann/json/issues/850) +- misclick, please ignore [\#849](https://github.com/nlohmann/json/issues/849) +- Make XML great again. [\#847](https://github.com/nlohmann/json/issues/847) +- Converting to array not working [\#843](https://github.com/nlohmann/json/issues/843) +- Iteration weirdness [\#842](https://github.com/nlohmann/json/issues/842) +- Use reference or pointer as Object value [\#841](https://github.com/nlohmann/json/issues/841) +- Ambiguity in parsing nested maps [\#840](https://github.com/nlohmann/json/issues/840) +- could not find from\_json\(\) method in T's namespace [\#839](https://github.com/nlohmann/json/issues/839) +- Incorrect parse error with binary data in keys? [\#838](https://github.com/nlohmann/json/issues/838) +- using dump\(\) when std::wstring is StringType with VS2017 [\#836](https://github.com/nlohmann/json/issues/836) +- Show the path of the currently parsed value when an error occurs [\#835](https://github.com/nlohmann/json/issues/835) +- Repetitive data type while reading [\#833](https://github.com/nlohmann/json/issues/833) +- Storing multiple types inside map [\#831](https://github.com/nlohmann/json/issues/831) +- Application terminating [\#830](https://github.com/nlohmann/json/issues/830) +- Missing CMake hunter package? [\#828](https://github.com/nlohmann/json/issues/828) +- std::map\ from json object yields C2665: 'std::pair\::pair': none of the 2 overloads could convert all the argument types [\#827](https://github.com/nlohmann/json/issues/827) +- object.dump gives quoted string, want to use .dump\(\) to generate javascripts. [\#826](https://github.com/nlohmann/json/issues/826) +- Assertion failed on \["NoExistKey"\] of an not existing key of const json& [\#825](https://github.com/nlohmann/json/issues/825) +- vs2015 error : static member will remain uninitialized at runtime but use in constant-expressions is supported [\#824](https://github.com/nlohmann/json/issues/824) +- Code Checking Warnings from json.hpp on VS2017 Community [\#821](https://github.com/nlohmann/json/issues/821) +- Missing iostream in try online [\#820](https://github.com/nlohmann/json/issues/820) +- Floating point value loses decimal point during dump [\#818](https://github.com/nlohmann/json/issues/818) +- Conan package for the library [\#817](https://github.com/nlohmann/json/issues/817) +- stream error [\#815](https://github.com/nlohmann/json/issues/815) +- Link error when using find\(\) on the latest commit [\#814](https://github.com/nlohmann/json/issues/814) +- ABI issue with json object between 2 shared libraries [\#813](https://github.com/nlohmann/json/issues/813) +- scan\_string\(\) return token\_type::parse\_error; when parse ansi file [\#812](https://github.com/nlohmann/json/issues/812) +- segfault when using fifo\_map with json [\#810](https://github.com/nlohmann/json/issues/810) +- This shit is shit [\#809](https://github.com/nlohmann/json/issues/809) +- \_finite and \_isnan are no members of "std" [\#808](https://github.com/nlohmann/json/issues/808) +- how to print out the line which causing exception? [\#806](https://github.com/nlohmann/json/issues/806) +- {} uses copy constructor, while = does not [\#805](https://github.com/nlohmann/json/issues/805) +- json.hpp:8955: multiple definition of function that is not defined twice or more. [\#804](https://github.com/nlohmann/json/issues/804) +- \[question\] to\_json for base and derived class [\#803](https://github.com/nlohmann/json/issues/803) +- Misleading error message - unexpected '"' - on incorrect utf-8 symbol [\#802](https://github.com/nlohmann/json/issues/802) +- json data = std::string\_view\("hi"\); doesn't work? [\#801](https://github.com/nlohmann/json/issues/801) +- Thread safety of parse\(\) [\#800](https://github.com/nlohmann/json/issues/800) +- Numbers as strings [\#799](https://github.com/nlohmann/json/issues/799) +- Tests failing on arm [\#797](https://github.com/nlohmann/json/issues/797) +- Using your library \(without modification\) in another library [\#796](https://github.com/nlohmann/json/issues/796) +- Iterating over sub-object [\#794](https://github.com/nlohmann/json/issues/794) +- how to get the json object again from which printed by the method of dump\(\) [\#792](https://github.com/nlohmann/json/issues/792) +- ppa to include source [\#791](https://github.com/nlohmann/json/issues/791) +- Different include paths in macOS and Ubuntu [\#790](https://github.com/nlohmann/json/issues/790) +- Missing break after line 12886 in switch/case [\#789](https://github.com/nlohmann/json/issues/789) +- All unit tests fail? [\#787](https://github.com/nlohmann/json/issues/787) +- More use of move semantics in deserialization [\#786](https://github.com/nlohmann/json/issues/786) +- warning C4706 - Visual Studio 2017 \(/W4\) [\#784](https://github.com/nlohmann/json/issues/784) +- Compile error in clang 5.0 [\#782](https://github.com/nlohmann/json/issues/782) +- Error Installing appium\_lib with Ruby v2.4.2 Due to JSON [\#781](https://github.com/nlohmann/json/issues/781) +- ::get\\(\) fails in new\(er\) release \[MSVC\] [\#780](https://github.com/nlohmann/json/issues/780) +- Type Conversion [\#779](https://github.com/nlohmann/json/issues/779) +- Segfault on nested parsing [\#778](https://github.com/nlohmann/json/issues/778) +- Build warnings: shadowing exception id [\#776](https://github.com/nlohmann/json/issues/776) +- multi-level JSON support. [\#775](https://github.com/nlohmann/json/issues/775) +- SIGABRT on dump\(\) [\#773](https://github.com/nlohmann/json/issues/773) +- \[Question\] Custom StringType template parameter \(possibility for a KeyType template parameter\) [\#772](https://github.com/nlohmann/json/issues/772) +- constexpr ALL the Things! [\#771](https://github.com/nlohmann/json/issues/771) +- error: ‘BasicJsonType’ in namespace ‘::’ does not name a type [\#770](https://github.com/nlohmann/json/issues/770) +- Program calls abort function [\#769](https://github.com/nlohmann/json/issues/769) +- \[Question\] Floating point resolution config during dump\(\) ? [\#768](https://github.com/nlohmann/json/issues/768) +- make check - no test ran [\#767](https://github.com/nlohmann/json/issues/767) +- The library cannot work properly with custom allocator based containers [\#766](https://github.com/nlohmann/json/issues/766) +- Documentation or feature request. [\#763](https://github.com/nlohmann/json/issues/763) +- warnings in msvc about mix/max macro while windows.h is used in the project [\#762](https://github.com/nlohmann/json/issues/762) +- std::signbit ambiguous [\#761](https://github.com/nlohmann/json/issues/761) +- How to use value for std::experimental::optional type? [\#760](https://github.com/nlohmann/json/issues/760) +- Cannot load json file properly [\#759](https://github.com/nlohmann/json/issues/759) +- Compilation error with unordered\_map\< int, int \> [\#758](https://github.com/nlohmann/json/issues/758) +- CBOR string [\#757](https://github.com/nlohmann/json/issues/757) +- Proposal: out\_of\_range should be a subclass of std::out\_of\_range [\#756](https://github.com/nlohmann/json/issues/756) +- Getter is setting the value to null if the key does not exist [\#754](https://github.com/nlohmann/json/issues/754) +- parsing works sometimes and crashes others [\#752](https://github.com/nlohmann/json/issues/752) +- Static\_assert failed "incompatible pointer type" with Xcode [\#751](https://github.com/nlohmann/json/issues/751) +- user-defined literal operator not found [\#750](https://github.com/nlohmann/json/issues/750) +- getting clean string from it.key\(\) [\#748](https://github.com/nlohmann/json/issues/748) +- Best method for exploring and obtaining values of nested json objects when the names are not known beforehand? [\#747](https://github.com/nlohmann/json/issues/747) +- null char at the end of string [\#746](https://github.com/nlohmann/json/issues/746) +- Incorrect sample for operator \>\> in docs [\#745](https://github.com/nlohmann/json/issues/745) +- User-friendly documentation [\#744](https://github.com/nlohmann/json/issues/744) +- Retrieve all values that match a json path [\#743](https://github.com/nlohmann/json/issues/743) +- Compilation issue with gcc 7.2 [\#742](https://github.com/nlohmann/json/issues/742) +- CMake target nlohmann\_json does not have src into its interface includes [\#741](https://github.com/nlohmann/json/issues/741) +- Error when serializing empty json: type must be string, but is object [\#740](https://github.com/nlohmann/json/issues/740) +- Conversion error for std::map\ [\#739](https://github.com/nlohmann/json/issues/739) +- Dumping Json to file as array [\#738](https://github.com/nlohmann/json/issues/738) +- nesting json objects [\#737](https://github.com/nlohmann/json/issues/737) +- where to find general help? [\#736](https://github.com/nlohmann/json/issues/736) +- Compilation Error on Clang 5.0 Upgrade [\#735](https://github.com/nlohmann/json/issues/735) +- Compilation error with std::map\ on vs 2015 [\#734](https://github.com/nlohmann/json/issues/734) +- Benchmarks for Binary formats [\#733](https://github.com/nlohmann/json/issues/733) +- Support \n symbols in json string. [\#731](https://github.com/nlohmann/json/issues/731) +- Project's name is too generic and hard to search for [\#730](https://github.com/nlohmann/json/issues/730) +- Visual Studio 2015 IntelliTrace problems [\#729](https://github.com/nlohmann/json/issues/729) +- How to erase nested objects inside other objects? [\#728](https://github.com/nlohmann/json/issues/728) +- Serialization for CBOR [\#726](https://github.com/nlohmann/json/issues/726) +- Using json Object as value in a map [\#725](https://github.com/nlohmann/json/issues/725) +- std::regex and nlohmann::json value [\#724](https://github.com/nlohmann/json/issues/724) +- Warnings when compiling with VisualStudio 2015 [\#723](https://github.com/nlohmann/json/issues/723) +- Has this lib the unicode \(wstring\) support? [\#722](https://github.com/nlohmann/json/issues/722) +- When will be 3.0 in master? [\#721](https://github.com/nlohmann/json/issues/721) +- Determine the type from error message. [\#720](https://github.com/nlohmann/json/issues/720) +- Compile-Error C2100 \(MS VS2015\) in line 887 json.hpp [\#719](https://github.com/nlohmann/json/issues/719) +- from\_json not working for boost::optional example [\#718](https://github.com/nlohmann/json/issues/718) +- about from\_json and to\_json function [\#717](https://github.com/nlohmann/json/issues/717) +- How to detect parse failure? [\#715](https://github.com/nlohmann/json/issues/715) +- Parse throw std::ios\_base::failure exception when failbit set to true [\#714](https://github.com/nlohmann/json/issues/714) +- Is there a way of format just making a pretty print without changing the key's orders ? [\#713](https://github.com/nlohmann/json/issues/713) +- Serialization of array of not same model items [\#712](https://github.com/nlohmann/json/issues/712) +- pointer to json parse vector [\#711](https://github.com/nlohmann/json/issues/711) +- Gtest SEH Exception [\#709](https://github.com/nlohmann/json/issues/709) +- broken from\_json implementation for pair and tuple [\#707](https://github.com/nlohmann/json/issues/707) +- Unevaluated lambda in assert breaks gcc 7 build [\#705](https://github.com/nlohmann/json/issues/705) +- Issues when adding values to firebase database [\#704](https://github.com/nlohmann/json/issues/704) +- Floating point equality - revisited [\#703](https://github.com/nlohmann/json/issues/703) +- Conversion from valarray\ to json fails to build [\#702](https://github.com/nlohmann/json/issues/702) +- internal compiler error \(gcc7\) [\#701](https://github.com/nlohmann/json/issues/701) +- One build system to rule them all [\#698](https://github.com/nlohmann/json/issues/698) +- Generated nlohmann\_jsonConfig.cmake does not set JSON\_INCLUDE\_DIR [\#695](https://github.com/nlohmann/json/issues/695) +- support the Chinese language in json string [\#694](https://github.com/nlohmann/json/issues/694) +- NaN problem within develop branch [\#693](https://github.com/nlohmann/json/issues/693) +- Please post example of specialization for boost::filesystem [\#692](https://github.com/nlohmann/json/issues/692) +- Impossible to do an array of composite objects [\#691](https://github.com/nlohmann/json/issues/691) +- How to save json to file? [\#690](https://github.com/nlohmann/json/issues/690) +- my simple json parser [\#689](https://github.com/nlohmann/json/issues/689) +- problem with new struct parsing syntax [\#688](https://github.com/nlohmann/json/issues/688) +- Parse error while parse the json string contains UTF 8 encoded document bytes string [\#684](https://github.com/nlohmann/json/issues/684) +- \[question\] how to get a string value by pointer [\#683](https://github.com/nlohmann/json/issues/683) +- create json object from string variable [\#681](https://github.com/nlohmann/json/issues/681) +- adl\_serializer and CRTP [\#680](https://github.com/nlohmann/json/issues/680) +- Is there a way to control the precision of serialized floating point numbers? [\#677](https://github.com/nlohmann/json/issues/677) +- Is there a way to get the path of a value? [\#676](https://github.com/nlohmann/json/issues/676) +- Could the parser locate errors to line? [\#675](https://github.com/nlohmann/json/issues/675) +- There is performance inefficiency found by coverity tool json2.1.1/include/nlohmann/json.hpp [\#673](https://github.com/nlohmann/json/issues/673) +- include problem, when cmake on osx [\#672](https://github.com/nlohmann/json/issues/672) +- Operator= ambiguous in C++1z and GCC 7.1.1 [\#670](https://github.com/nlohmann/json/issues/670) +- should't the cmake install target be to nlohman/json.hpp [\#668](https://github.com/nlohmann/json/issues/668) +- deserialise from `std::vector` [\#667](https://github.com/nlohmann/json/issues/667) +- How to iterate? [\#665](https://github.com/nlohmann/json/issues/665) +- could this json lib work on windows? [\#664](https://github.com/nlohmann/json/issues/664) +- How does from\_json work? [\#662](https://github.com/nlohmann/json/issues/662) +- insert\(or merge\) object should replace same key , not ignore [\#661](https://github.com/nlohmann/json/issues/661) +- Parse method doesn't handle newlines. [\#659](https://github.com/nlohmann/json/issues/659) +- Compilation "note" on GCC 6 ARM [\#658](https://github.com/nlohmann/json/issues/658) +- Adding additional push\_back/operator+= rvalue overloads for JSON object [\#657](https://github.com/nlohmann/json/issues/657) +- dump's parameter "ensure\_ascii" creates too long sequences [\#656](https://github.com/nlohmann/json/issues/656) +- Question: parsing `void *` [\#655](https://github.com/nlohmann/json/issues/655) +- how should I check a string is valid JSON string ? [\#653](https://github.com/nlohmann/json/issues/653) +- Question: thread safety of read only accesses [\#651](https://github.com/nlohmann/json/issues/651) +- Eclipse: Method 'size' could not be resolved [\#649](https://github.com/nlohmann/json/issues/649) +- Update/Add object fields [\#648](https://github.com/nlohmann/json/issues/648) +- No exception raised for Out Of Range input of numbers [\#647](https://github.com/nlohmann/json/issues/647) +- Package Name [\#646](https://github.com/nlohmann/json/issues/646) +- What is the meaning of operator\[\]\(T\* key\) [\#645](https://github.com/nlohmann/json/issues/645) +- Which is the correct way to json objects as parameters to functions? [\#644](https://github.com/nlohmann/json/issues/644) +- Method to get string representations of values [\#642](https://github.com/nlohmann/json/issues/642) +- CBOR serialization of a given JSON value does not serialize [\#641](https://github.com/nlohmann/json/issues/641) +- Are we forced to use "-fexceptions" flag in android ndk project [\#640](https://github.com/nlohmann/json/issues/640) +- Comparison of objects containing floats [\#639](https://github.com/nlohmann/json/issues/639) +- 'localeconv' is not supported by NDK for SDK \<=20 [\#638](https://github.com/nlohmann/json/issues/638) +- \[Question\] cLion integration [\#637](https://github.com/nlohmann/json/issues/637) +- How to construct an iteratable usage in nlohmann json? [\#636](https://github.com/nlohmann/json/issues/636) +- \[Question\] copy assign json-container to vector [\#635](https://github.com/nlohmann/json/issues/635) +- Get size without .dump\(\) [\#634](https://github.com/nlohmann/json/issues/634) +- Segmentation fault when parsing invalid json file [\#633](https://github.com/nlohmann/json/issues/633) +- How to serialize from json to vector\? [\#632](https://github.com/nlohmann/json/issues/632) +- no member named 'thousands\_sep' in 'lconv' [\#631](https://github.com/nlohmann/json/issues/631) +- \[Question\] Any fork for \(the unsupported\) Visual Studio 2012 version? [\#628](https://github.com/nlohmann/json/issues/628) +- Dependency injection in serializer [\#627](https://github.com/nlohmann/json/issues/627) +- from\_json for std::array [\#625](https://github.com/nlohmann/json/issues/625) +- Discussion: How to structure the parsing function families [\#623](https://github.com/nlohmann/json/issues/623) +- Question: How to erase subtree [\#622](https://github.com/nlohmann/json/issues/622) +- Insertion into nested json field [\#621](https://github.com/nlohmann/json/issues/621) +- Question: return static json object from function [\#618](https://github.com/nlohmann/json/issues/618) +- icc16 error [\#617](https://github.com/nlohmann/json/issues/617) +- \[-Wdeprecated-declarations\] in row `j >> ss;` in file `json.hpp:7405:26` and FAILED unit tests with MinGWx64! [\#616](https://github.com/nlohmann/json/issues/616) +- to\_json for pairs, tuples [\#614](https://github.com/nlohmann/json/issues/614) +- Using uninitialized memory 'buf' in line 11173 v2.1.1? [\#613](https://github.com/nlohmann/json/issues/613) +- How to parse multiple same Keys of JSON and save them? [\#612](https://github.com/nlohmann/json/issues/612) +- "Multiple declarations" error when using types defined with `typedef` [\#611](https://github.com/nlohmann/json/issues/611) +- 2.1.1+ breaks compilation of shared\_ptr\ == 0 [\#610](https://github.com/nlohmann/json/issues/610) +- a bug of inheritance ? [\#608](https://github.com/nlohmann/json/issues/608) +- std::map key conversion with to\_json [\#607](https://github.com/nlohmann/json/issues/607) +- json.hpp:6384:62: error: wrong number of template arguments \(1, should be 2\) [\#606](https://github.com/nlohmann/json/issues/606) +- Incremental parsing: Where's the push version? [\#605](https://github.com/nlohmann/json/issues/605) +- Is there a way to validate the structure of a json object ? [\#604](https://github.com/nlohmann/json/issues/604) +- \[Question\] Issue when using Appveyor when compiling library [\#603](https://github.com/nlohmann/json/issues/603) +- BOM not skipped when using json:parse\(iterator\) [\#602](https://github.com/nlohmann/json/issues/602) +- Use of the binary type in CBOR and Message Pack [\#601](https://github.com/nlohmann/json/issues/601) +- Newbie issue: how does one convert a map in Json back to std::map? [\#600](https://github.com/nlohmann/json/issues/600) +- Plugin system [\#599](https://github.com/nlohmann/json/issues/599) +- Using custom types for scalars? [\#596](https://github.com/nlohmann/json/issues/596) +- Issues with the arithmetic in iterator and reverse iterator [\#593](https://github.com/nlohmann/json/issues/593) +- not enough examples [\#592](https://github.com/nlohmann/json/issues/592) +- in-class initialization for type 'const T' is not yet implemented [\#591](https://github.com/nlohmann/json/issues/591) +- compiling with gcc 7 -\> error on bool operator \< [\#590](https://github.com/nlohmann/json/issues/590) +- Parsing from stream leads to an array [\#589](https://github.com/nlohmann/json/issues/589) +- Buggy support for binary string data [\#587](https://github.com/nlohmann/json/issues/587) +- C++17's ambiguous conversion [\#586](https://github.com/nlohmann/json/issues/586) +- How does the messagepack encoding/decoding compare to msgpack-cpp in terms of performance? [\#585](https://github.com/nlohmann/json/issues/585) +- is it possible to check existence of a value deep in hierarchy? [\#584](https://github.com/nlohmann/json/issues/584) +- loading from a stream and exceptions [\#582](https://github.com/nlohmann/json/issues/582) +- Visual Studio seems not to have all min\(\) function versions [\#581](https://github.com/nlohmann/json/issues/581) +- Supporting of the json schema [\#580](https://github.com/nlohmann/json/issues/580) +- Stack-overflow \(OSS-Fuzz 1444\) [\#577](https://github.com/nlohmann/json/issues/577) +- Heap-buffer-overflow \(OSS-Fuzz 1400\) [\#575](https://github.com/nlohmann/json/issues/575) +- JSON escape quotes [\#574](https://github.com/nlohmann/json/issues/574) +- error: static\_assert failed [\#573](https://github.com/nlohmann/json/issues/573) +- Storing floats, and round trip serialisation/deserialisation diffs [\#572](https://github.com/nlohmann/json/issues/572) +- JSON.getLong produces inconsistent results [\#571](https://github.com/nlohmann/json/issues/571) +- Request: Object.at\(\) with default return value [\#570](https://github.com/nlohmann/json/issues/570) +- Internal structure gets corrupted while parsing [\#569](https://github.com/nlohmann/json/issues/569) +- create template \ basic\_json from\_cbor\(Iter begin, Iter end\) [\#568](https://github.com/nlohmann/json/issues/568) +- Conan.io [\#566](https://github.com/nlohmann/json/issues/566) +- contradictory documentation regarding json::find [\#565](https://github.com/nlohmann/json/issues/565) +- Unexpected '\"' in middle of array [\#564](https://github.com/nlohmann/json/issues/564) +- Support parse std::pair to Json object [\#563](https://github.com/nlohmann/json/issues/563) +- json and Microsoft Visual c++ Compiler Nov 2012 CTP [\#562](https://github.com/nlohmann/json/issues/562) +- from\_json declaration order and exceptions [\#561](https://github.com/nlohmann/json/issues/561) +- Tip: Don't upgrade to VS2017 if using json initializer list constructs [\#559](https://github.com/nlohmann/json/issues/559) +- parse error - unexpected end of input [\#558](https://github.com/nlohmann/json/issues/558) +- Cant modify existing numbers inside a json object [\#557](https://github.com/nlohmann/json/issues/557) +- Better support for SAX style serialize and deserialize in new version? [\#554](https://github.com/nlohmann/json/issues/554) +- Cannot convert from json array to std::array [\#553](https://github.com/nlohmann/json/issues/553) +- Do not define an unnamed namespace in a header file \(DCL59-CPP\) [\#552](https://github.com/nlohmann/json/issues/552) +- Parse error on known good json file [\#551](https://github.com/nlohmann/json/issues/551) +- Warning on Intel compiler \(icc 17\) [\#550](https://github.com/nlohmann/json/issues/550) +- multiple versions of 'vsnprintf' [\#549](https://github.com/nlohmann/json/issues/549) +- illegal indirection [\#548](https://github.com/nlohmann/json/issues/548) +- Ambiguous compare operators with clang-5.0 [\#547](https://github.com/nlohmann/json/issues/547) +- Using tsl::ordered\_map [\#546](https://github.com/nlohmann/json/issues/546) +- Compiler support errors are inconvenient [\#544](https://github.com/nlohmann/json/issues/544) +- Duplicate symbols error happens while to\_json/from\_json method implemented inside entity definition header file [\#542](https://github.com/nlohmann/json/issues/542) +- consider adding a bool json::is\_valid\(std::string const&\) non-member function [\#541](https://github.com/nlohmann/json/issues/541) +- Help request [\#539](https://github.com/nlohmann/json/issues/539) +- How to deal with missing keys in `from_json`? [\#538](https://github.com/nlohmann/json/issues/538) +- recursive from\_msgpack implementation will stack overflow [\#537](https://github.com/nlohmann/json/issues/537) +- Exception objects must be nothrow copy constructible \(ERR60-CPP\) [\#531](https://github.com/nlohmann/json/issues/531) +- Support for multiple root elements [\#529](https://github.com/nlohmann/json/issues/529) +- Port has\_shape from dropbox/json11 [\#528](https://github.com/nlohmann/json/issues/528) +- dump\_float: truncation from ptrdiff\_t to long [\#527](https://github.com/nlohmann/json/issues/527) +- Make exception base class visible in basic\_json [\#525](https://github.com/nlohmann/json/issues/525) +- msgpack unit test failures on ppc64 arch [\#524](https://github.com/nlohmann/json/issues/524) +- How about split the implementation out, and only leave the interface? [\#523](https://github.com/nlohmann/json/issues/523) +- VC++2017 not enough actual parameters for macro 'max' [\#522](https://github.com/nlohmann/json/issues/522) +- crash on empty ifstream [\#521](https://github.com/nlohmann/json/issues/521) +- Suggestion: Support tabs for indentation when serializing to stream. [\#520](https://github.com/nlohmann/json/issues/520) +- Abrt in get\_number \(OSS-Fuzz 885\) [\#519](https://github.com/nlohmann/json/issues/519) +- Abrt on unknown address \(OSS-Fuzz 884\) [\#518](https://github.com/nlohmann/json/issues/518) +- Stack-overflow \(OSS-Fuzz 869\) [\#517](https://github.com/nlohmann/json/issues/517) +- Assertion error \(OSS-Fuzz 868\) [\#516](https://github.com/nlohmann/json/issues/516) +- NaN to json and back [\#515](https://github.com/nlohmann/json/issues/515) +- Comparison of NaN [\#514](https://github.com/nlohmann/json/issues/514) +- why it's not possible to serialize c++11 enums directly [\#513](https://github.com/nlohmann/json/issues/513) +- clang compile error: use of overloaded operator '\<=' is ambiguous with \(nlohmann::json{{"a", 5}}\)\["a"\] \<= 10 [\#512](https://github.com/nlohmann/json/issues/512) +- Why not also look inside the type for \(static\) to\_json and from\_json funtions? [\#511](https://github.com/nlohmann/json/issues/511) +- Parser issues [\#509](https://github.com/nlohmann/json/issues/509) +- I may not understand [\#507](https://github.com/nlohmann/json/issues/507) +- VS2017 min / max problem for 2.1.1 [\#506](https://github.com/nlohmann/json/issues/506) +- CBOR/MessagePack is not read until the end [\#505](https://github.com/nlohmann/json/issues/505) +- Assertion error \(OSS-Fuzz 856\) [\#504](https://github.com/nlohmann/json/issues/504) +- Return position in parse error exceptions [\#503](https://github.com/nlohmann/json/issues/503) +- conversion from/to C array is not supported [\#502](https://github.com/nlohmann/json/issues/502) +- error C2338: could not find to\_json\(\) method in T's namespace [\#501](https://github.com/nlohmann/json/issues/501) +- Test suite fails in en\_GB.UTF-8 [\#500](https://github.com/nlohmann/json/issues/500) +- cannot use operator\[\] with number [\#499](https://github.com/nlohmann/json/issues/499) +- consider using \_\_cpp\_exceptions and/or \_\_EXCEPTIONS to disable/enable exception support [\#498](https://github.com/nlohmann/json/issues/498) +- Stack-overflow \(OSS-Fuzz issue 814\) [\#497](https://github.com/nlohmann/json/issues/497) +- Using in Unreal Engine - handling custom types conversion [\#495](https://github.com/nlohmann/json/issues/495) +- Conversion from vector\ to json fails to build [\#494](https://github.com/nlohmann/json/issues/494) +- fill\_line\_buffer incorrectly tests m\_stream for eof but not fail or bad bits [\#493](https://github.com/nlohmann/json/issues/493) +- Compiling with \_GLIBCXX\_DEBUG yields iterator-comparison warnings during tests [\#492](https://github.com/nlohmann/json/issues/492) +- crapy interface [\#491](https://github.com/nlohmann/json/issues/491) +- Fix Visual Studo 2013 builds. [\#490](https://github.com/nlohmann/json/issues/490) +- Failed to compile with -D\_GLIBCXX\_PARALLEL [\#489](https://github.com/nlohmann/json/issues/489) +- Input several field with the same name [\#488](https://github.com/nlohmann/json/issues/488) +- read in .json file yields strange sizes [\#487](https://github.com/nlohmann/json/issues/487) +- json::value\_t can't be a map's key type in VC++ 2015 [\#486](https://github.com/nlohmann/json/issues/486) +- Using fifo\_map [\#485](https://github.com/nlohmann/json/issues/485) +- Cannot get float pointer for value stored as `0` [\#484](https://github.com/nlohmann/json/issues/484) +- byte string support [\#483](https://github.com/nlohmann/json/issues/483) +- https://github.com/nlohmann/json\#execute-unit-tests [\#481](https://github.com/nlohmann/json/issues/481) +- Remove deprecated constructor basic\_json\(std::istream&\) [\#480](https://github.com/nlohmann/json/issues/480) +- writing the binary json file? [\#479](https://github.com/nlohmann/json/issues/479) +- CBOR/MessagePack from uint8\_t \* and size [\#478](https://github.com/nlohmann/json/issues/478) +- Streaming binary representations [\#477](https://github.com/nlohmann/json/issues/477) +- Reuse memory in to\_cbor and to\_msgpack functions [\#476](https://github.com/nlohmann/json/issues/476) +- Error Using JSON Library with arrays C++ [\#475](https://github.com/nlohmann/json/issues/475) +- Moving forward to version 3.0.0 [\#474](https://github.com/nlohmann/json/issues/474) +- Inconsistent behavior in conversion to array type [\#473](https://github.com/nlohmann/json/issues/473) +- Create a \[key:member\_pointer\] map to ease parsing custom types [\#471](https://github.com/nlohmann/json/issues/471) +- MSVC 2015 update 2 [\#469](https://github.com/nlohmann/json/issues/469) +- VS2017 implicit to std::string conversion fix. [\#464](https://github.com/nlohmann/json/issues/464) +- How to make sure a string or string literal is a valid JSON? [\#458](https://github.com/nlohmann/json/issues/458) +- basic\_json templated on a "policy" class [\#456](https://github.com/nlohmann/json/issues/456) +- json::value\(const json\_pointer&, ValueType\) requires exceptions to return the default value. [\#440](https://github.com/nlohmann/json/issues/440) +- is it possible merge two json object [\#428](https://github.com/nlohmann/json/issues/428) +- Is it possible to turn this into a shared library? [\#420](https://github.com/nlohmann/json/issues/420) +- Further thoughts on performance improvements [\#418](https://github.com/nlohmann/json/issues/418) +- nan number stored as null [\#388](https://github.com/nlohmann/json/issues/388) +- Behavior of operator\>\> should more closely resemble that of built-in overloads. [\#367](https://github.com/nlohmann/json/issues/367) +- Request: range-based-for over a json-object to expose .first/.second [\#350](https://github.com/nlohmann/json/issues/350) +- feature wish: JSONPath [\#343](https://github.com/nlohmann/json/issues/343) +- UTF-8/Unicode escape and dump [\#330](https://github.com/nlohmann/json/issues/330) +- Serialized value not always can be parsed. [\#329](https://github.com/nlohmann/json/issues/329) +- Is there a way to forward declare nlohmann::json? [\#314](https://github.com/nlohmann/json/issues/314) +- Exception line [\#301](https://github.com/nlohmann/json/issues/301) +- Do not throw exception when default\_value's type does not match the actual type [\#278](https://github.com/nlohmann/json/issues/278) +- dump\(\) method doesn't work with a custom allocator [\#268](https://github.com/nlohmann/json/issues/268) +- Readme documentation enhancements [\#248](https://github.com/nlohmann/json/issues/248) +- Use user-defined exceptions [\#244](https://github.com/nlohmann/json/issues/244) +- Incorrect C++11 allocator model support [\#161](https://github.com/nlohmann/json/issues/161) + +- :white\_check\_mark: re-added tests for algorithms [\#879](https://github.com/nlohmann/json/pull/879) ([nlohmann](https://github.com/nlohmann)) +- Overworked library toward 3.0.0 release [\#875](https://github.com/nlohmann/json/pull/875) ([nlohmann](https://github.com/nlohmann)) +- :rotating\_light: remove C4996 warnings \#872 [\#873](https://github.com/nlohmann/json/pull/873) ([nlohmann](https://github.com/nlohmann)) +- :boom: throwing an exception in case dump encounters a non-UTF-8 string \#838 [\#870](https://github.com/nlohmann/json/pull/870) ([nlohmann](https://github.com/nlohmann)) +- :memo: fixing documentation \#867 [\#868](https://github.com/nlohmann/json/pull/868) ([nlohmann](https://github.com/nlohmann)) +- iter\_impl template conformance with C++17 [\#860](https://github.com/nlohmann/json/pull/860) ([bogemic](https://github.com/bogemic)) +- Std allocator conformance cpp17 [\#856](https://github.com/nlohmann/json/pull/856) ([bogemic](https://github.com/bogemic)) +- cmake: use BUILD\_INTERFACE/INSTALL\_INTERFACE [\#855](https://github.com/nlohmann/json/pull/855) ([theodelrieu](https://github.com/theodelrieu)) +- to/from\_json: add a MSVC-specific static\_assert to force a stacktrace [\#854](https://github.com/nlohmann/json/pull/854) ([theodelrieu](https://github.com/theodelrieu)) +- Add .natvis for MSVC debug view [\#844](https://github.com/nlohmann/json/pull/844) ([TinyTinni](https://github.com/TinyTinni)) +- Updated hunter package links [\#829](https://github.com/nlohmann/json/pull/829) ([jowr](https://github.com/jowr)) +- Typos README [\#811](https://github.com/nlohmann/json/pull/811) ([Itja](https://github.com/Itja)) +- add forwarding references to json\_ref constructor [\#807](https://github.com/nlohmann/json/pull/807) ([theodelrieu](https://github.com/theodelrieu)) +- Add transparent comparator and perfect forwarding support to find\(\) and count\(\) [\#795](https://github.com/nlohmann/json/pull/795) ([jseward](https://github.com/jseward)) +- Error : 'identifier "size\_t" is undefined' in linux [\#793](https://github.com/nlohmann/json/pull/793) ([sonulohani](https://github.com/sonulohani)) +- Fix Visual Studio 2017 warnings [\#788](https://github.com/nlohmann/json/pull/788) ([jseward](https://github.com/jseward)) +- Fix warning C4706 on Visual Studio 2017 [\#785](https://github.com/nlohmann/json/pull/785) ([jseward](https://github.com/jseward)) +- Set GENERATE\_TAGFILE in Doxyfile [\#783](https://github.com/nlohmann/json/pull/783) ([eld00d](https://github.com/eld00d)) +- using more CMake [\#765](https://github.com/nlohmann/json/pull/765) ([nlohmann](https://github.com/nlohmann)) +- Simplified istream handing \#367 [\#764](https://github.com/nlohmann/json/pull/764) ([pjkundert](https://github.com/pjkundert)) +- Add info for the vcpkg package. [\#753](https://github.com/nlohmann/json/pull/753) ([gregmarr](https://github.com/gregmarr)) +- fix from\_json implementation for pair/tuple [\#708](https://github.com/nlohmann/json/pull/708) ([theodelrieu](https://github.com/theodelrieu)) +- Update json.hpp [\#686](https://github.com/nlohmann/json/pull/686) ([GoWebProd](https://github.com/GoWebProd)) +- Remove duplicate word [\#685](https://github.com/nlohmann/json/pull/685) ([daixtrose](https://github.com/daixtrose)) +- To fix compilation issue for intel OSX compiler [\#682](https://github.com/nlohmann/json/pull/682) ([kbthomp1](https://github.com/kbthomp1)) +- Digraph warning [\#679](https://github.com/nlohmann/json/pull/679) ([traits](https://github.com/traits)) +- massage -\> message [\#678](https://github.com/nlohmann/json/pull/678) ([DmitryKuk](https://github.com/DmitryKuk)) +- Fix "not constraint" grammar in docs [\#674](https://github.com/nlohmann/json/pull/674) ([wincent](https://github.com/wincent)) +- Add documentation for integration with CMake and hunter [\#671](https://github.com/nlohmann/json/pull/671) ([dan-42](https://github.com/dan-42)) +- REFACTOR: rewrite CMakeLists.txt for better inlcude and reuse [\#669](https://github.com/nlohmann/json/pull/669) ([dan-42](https://github.com/dan-42)) +- enable\_testing only if the JSON\_BuildTests is ON [\#666](https://github.com/nlohmann/json/pull/666) ([effolkronium](https://github.com/effolkronium)) +- Support moving from rvalues in std::initializer\_list [\#663](https://github.com/nlohmann/json/pull/663) ([himikof](https://github.com/himikof)) +- add ensure\_ascii parameter to dump. \#330 [\#654](https://github.com/nlohmann/json/pull/654) ([ryanjmulder](https://github.com/ryanjmulder)) +- Rename BuildTests to JSON\_BuildTests [\#652](https://github.com/nlohmann/json/pull/652) ([olegendo](https://github.com/olegendo)) +- Don't include \, use std::make\_shared [\#650](https://github.com/nlohmann/json/pull/650) ([olegendo](https://github.com/olegendo)) +- Refacto/split basic json [\#643](https://github.com/nlohmann/json/pull/643) ([theodelrieu](https://github.com/theodelrieu)) +- fix typo in operator\_\_notequal example [\#630](https://github.com/nlohmann/json/pull/630) ([Chocobo1](https://github.com/Chocobo1)) +- Fix MSVC warning C4819 [\#629](https://github.com/nlohmann/json/pull/629) ([Chocobo1](https://github.com/Chocobo1)) +- \[BugFix\] Add parentheses around std::min [\#626](https://github.com/nlohmann/json/pull/626) ([koemeet](https://github.com/koemeet)) +- add pair/tuple conversions [\#624](https://github.com/nlohmann/json/pull/624) ([theodelrieu](https://github.com/theodelrieu)) +- remove std::pair support [\#615](https://github.com/nlohmann/json/pull/615) ([theodelrieu](https://github.com/theodelrieu)) +- Add pair support, fix CompatibleObject conversions \(fixes \#600\) [\#609](https://github.com/nlohmann/json/pull/609) ([theodelrieu](https://github.com/theodelrieu)) +- \#550 Fix iterator related compiling issues for Intel icc [\#598](https://github.com/nlohmann/json/pull/598) ([HenryRLee](https://github.com/HenryRLee)) +- Issue \#593 Fix the arithmetic operators in the iterator and reverse iterator [\#595](https://github.com/nlohmann/json/pull/595) ([HenryRLee](https://github.com/HenryRLee)) +- fix doxygen error of basic\_json::get\(\) [\#583](https://github.com/nlohmann/json/pull/583) ([zhaohuaxishi](https://github.com/zhaohuaxishi)) +- Fixing assignement for iterator wrapper second, and adding unit test [\#579](https://github.com/nlohmann/json/pull/579) ([Type1J](https://github.com/Type1J)) +- Adding first and second properties to iteration\_proxy\_internal [\#578](https://github.com/nlohmann/json/pull/578) ([Type1J](https://github.com/Type1J)) +- Adding support for Meson. [\#576](https://github.com/nlohmann/json/pull/576) ([Type1J](https://github.com/Type1J)) +- add enum class default conversions [\#545](https://github.com/nlohmann/json/pull/545) ([theodelrieu](https://github.com/theodelrieu)) +- Properly pop diagnostics [\#540](https://github.com/nlohmann/json/pull/540) ([tinloaf](https://github.com/tinloaf)) +- Add Visual Studio 17 image to appveyor build matrix [\#536](https://github.com/nlohmann/json/pull/536) ([vpetrigo](https://github.com/vpetrigo)) +- UTF8 encoding enhancement [\#534](https://github.com/nlohmann/json/pull/534) ([TedLyngmo](https://github.com/TedLyngmo)) +- Fix typo [\#530](https://github.com/nlohmann/json/pull/530) ([berkus](https://github.com/berkus)) +- Make exception base class visible in basic\_json [\#526](https://github.com/nlohmann/json/pull/526) ([ghost](https://github.com/ghost)) +- :art: Namespace `uint8_t` from the C++ stdlib [\#510](https://github.com/nlohmann/json/pull/510) ([alexweej](https://github.com/alexweej)) +- add to\_json method for C arrays [\#508](https://github.com/nlohmann/json/pull/508) ([theodelrieu](https://github.com/theodelrieu)) +- Fix -Weffc++ warnings \(GNU 6.3.1\) [\#496](https://github.com/nlohmann/json/pull/496) ([TedLyngmo](https://github.com/TedLyngmo)) + +## [v2.1.1](https://github.com/nlohmann/json/releases/tag/v2.1.1) (2017-02-25) + +[Full Changelog](https://github.com/nlohmann/json/compare/2.1.1...v2.1.1) + +## [2.1.1](https://github.com/nlohmann/json/releases/tag/2.1.1) (2017-02-25) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.0...2.1.1) + +- warning in the library [\#472](https://github.com/nlohmann/json/issues/472) +- How to create an array of Objects? [\#470](https://github.com/nlohmann/json/issues/470) +- \[Bug?\] Cannot get int pointer, but int64\_t works [\#468](https://github.com/nlohmann/json/issues/468) +- Illegal indirection [\#467](https://github.com/nlohmann/json/issues/467) +- in vs can't find linkageId [\#466](https://github.com/nlohmann/json/issues/466) +- Roundtrip error while parsing "1000000000000000010E5" [\#465](https://github.com/nlohmann/json/issues/465) +- C4996 error and warning with Visual Studio [\#463](https://github.com/nlohmann/json/issues/463) +- Support startIndex for from\_cbor/from\_msgpack [\#462](https://github.com/nlohmann/json/issues/462) +- question: monospace font used in feature slideshow? [\#460](https://github.com/nlohmann/json/issues/460) +- Object.keys\(\) [\#459](https://github.com/nlohmann/json/issues/459) +- Use “, “ as delimiter for json-objects. [\#457](https://github.com/nlohmann/json/issues/457) +- Enum -\> string during serialization and vice versa [\#455](https://github.com/nlohmann/json/issues/455) +- doubles are printed as integers [\#454](https://github.com/nlohmann/json/issues/454) +- Warnings with Visual Studio c++ \(VS2015 Update 3\) [\#453](https://github.com/nlohmann/json/issues/453) +- Heap-buffer-overflow \(OSS-Fuzz issue 585\) [\#452](https://github.com/nlohmann/json/issues/452) +- use of undeclared identifier 'UINT8\_MAX' [\#451](https://github.com/nlohmann/json/issues/451) +- Question on the lifetime managment of objects at the lower levels [\#449](https://github.com/nlohmann/json/issues/449) +- Json should not be constructible with 'json\*' [\#448](https://github.com/nlohmann/json/issues/448) +- Move value\_t to namespace scope [\#447](https://github.com/nlohmann/json/issues/447) +- Typo in README.md [\#446](https://github.com/nlohmann/json/issues/446) +- make check compilation is unneccesarily slow [\#445](https://github.com/nlohmann/json/issues/445) +- Problem in dump\(\) in json.h caused by ss.imbue [\#444](https://github.com/nlohmann/json/issues/444) +- I want to create Windows Application in Visual Studio 2015 c++, and i have a problem [\#443](https://github.com/nlohmann/json/issues/443) +- Implicit conversion issues [\#442](https://github.com/nlohmann/json/issues/442) +- Parsing of floats locale dependent [\#302](https://github.com/nlohmann/json/issues/302) + +- Speedup CI builds using cotire [\#461](https://github.com/nlohmann/json/pull/461) ([tusharpm](https://github.com/tusharpm)) +- TurpentineDistillery feature/locale independent str to num [\#450](https://github.com/nlohmann/json/pull/450) ([nlohmann](https://github.com/nlohmann)) +- README: adjust boost::optional example [\#439](https://github.com/nlohmann/json/pull/439) ([jaredgrubb](https://github.com/jaredgrubb)) +- fix \#414 - comparing to 0 literal [\#415](https://github.com/nlohmann/json/pull/415) ([stanmihai4](https://github.com/stanmihai4)) +- locale-independent num-to-str [\#378](https://github.com/nlohmann/json/pull/378) ([TurpentineDistillery](https://github.com/TurpentineDistillery)) + +## [v2.1.0](https://github.com/nlohmann/json/releases/tag/v2.1.0) (2017-01-28) + +[Full Changelog](https://github.com/nlohmann/json/compare/2.1.0...v2.1.0) + +## [2.1.0](https://github.com/nlohmann/json/releases/tag/2.1.0) (2017-01-28) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.10...2.1.0) + +- Parsing multiple JSON objects from a string or stream [\#438](https://github.com/nlohmann/json/issues/438) +- Use-of-uninitialized-value \(OSS-Fuzz issue 477\) [\#437](https://github.com/nlohmann/json/issues/437) +- add `reserve` function for array to reserve memory before adding json values into it [\#436](https://github.com/nlohmann/json/issues/436) +- Typo in examples page [\#434](https://github.com/nlohmann/json/issues/434) +- avoid malformed json [\#433](https://github.com/nlohmann/json/issues/433) +- How to add json objects to a map? [\#432](https://github.com/nlohmann/json/issues/432) +- create json instance from raw json \(unsigned char\*\) [\#431](https://github.com/nlohmann/json/issues/431) +- Getting std::invalid\_argument: stream error when following example [\#429](https://github.com/nlohmann/json/issues/429) +- Forward declare-only header? [\#427](https://github.com/nlohmann/json/issues/427) +- Implicit conversion from array to object [\#425](https://github.com/nlohmann/json/issues/425) +- error C4996: 'strerror' when reading file [\#422](https://github.com/nlohmann/json/issues/422) +- Get an error - JSON pointer must be empty or begin with '/' [\#421](https://github.com/nlohmann/json/issues/421) +- size parameter for parse\(\) [\#419](https://github.com/nlohmann/json/issues/419) +- json.hpp forcibly defines GCC\_VERSION [\#417](https://github.com/nlohmann/json/issues/417) +- Use-of-uninitialized-value \(OSS-Fuzz issue 377\) [\#416](https://github.com/nlohmann/json/issues/416) +- comparing to 0 literal [\#414](https://github.com/nlohmann/json/issues/414) +- Single char converted to ASCII code instead of string [\#413](https://github.com/nlohmann/json/issues/413) +- How to know if a string was parsed as utf-8? [\#406](https://github.com/nlohmann/json/issues/406) +- Overloaded += to add objects to an array makes no sense? [\#404](https://github.com/nlohmann/json/issues/404) +- Finding a value in an array [\#399](https://github.com/nlohmann/json/issues/399) +- add release information in static function [\#397](https://github.com/nlohmann/json/issues/397) +- Optimize memory usage of json objects in combination with binary serialization [\#373](https://github.com/nlohmann/json/issues/373) +- Conversion operators not considered [\#369](https://github.com/nlohmann/json/issues/369) +- Append ".0" to serialized floating\_point values that are digits-only. [\#362](https://github.com/nlohmann/json/issues/362) +- Add a customization point for user-defined types [\#328](https://github.com/nlohmann/json/issues/328) +- Conformance report for reference [\#307](https://github.com/nlohmann/json/issues/307) +- Document the best way to serialize/deserialize user defined types to json [\#298](https://github.com/nlohmann/json/issues/298) +- Add StringView template typename to basic\_json [\#297](https://github.com/nlohmann/json/issues/297) +- \[Improvement\] Add option to remove exceptions [\#296](https://github.com/nlohmann/json/issues/296) +- Performance in miloyip/nativejson-benchmark [\#202](https://github.com/nlohmann/json/issues/202) + +- conversion from/to user-defined types [\#435](https://github.com/nlohmann/json/pull/435) ([nlohmann](https://github.com/nlohmann)) +- Fix documentation error [\#430](https://github.com/nlohmann/json/pull/430) ([vjon](https://github.com/vjon)) + +## [v2.0.10](https://github.com/nlohmann/json/releases/tag/v2.0.10) (2017-01-02) + +[Full Changelog](https://github.com/nlohmann/json/compare/2.0.10...v2.0.10) + +## [2.0.10](https://github.com/nlohmann/json/releases/tag/2.0.10) (2017-01-02) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.9...2.0.10) + +- Heap-buffer-overflow \(OSS-Fuzz issue 367\) [\#412](https://github.com/nlohmann/json/issues/412) +- Heap-buffer-overflow \(OSS-Fuzz issue 366\) [\#411](https://github.com/nlohmann/json/issues/411) +- Use-of-uninitialized-value \(OSS-Fuzz issue 347\) [\#409](https://github.com/nlohmann/json/issues/409) +- Heap-buffer-overflow \(OSS-Fuzz issue 344\) [\#408](https://github.com/nlohmann/json/issues/408) +- Heap-buffer-overflow \(OSS-Fuzz issue 343\) [\#407](https://github.com/nlohmann/json/issues/407) +- Heap-buffer-overflow \(OSS-Fuzz issue 342\) [\#405](https://github.com/nlohmann/json/issues/405) +- strerror throwing error in compiler VS2015 [\#403](https://github.com/nlohmann/json/issues/403) +- json::parse of std::string being underlined by Visual Studio [\#402](https://github.com/nlohmann/json/issues/402) +- Explicitly getting string without .dump\(\) [\#401](https://github.com/nlohmann/json/issues/401) +- Possible to speed up json::parse? [\#398](https://github.com/nlohmann/json/issues/398) +- the alphabetic order in the code influence console\_output. [\#396](https://github.com/nlohmann/json/issues/396) +- Execute tests with clang sanitizers [\#394](https://github.com/nlohmann/json/issues/394) +- Check if library can be used with ETL [\#361](https://github.com/nlohmann/json/issues/361) + +- Feature/clang sanitize [\#410](https://github.com/nlohmann/json/pull/410) ([Daniel599](https://github.com/Daniel599)) +- Add Doozer build badge [\#400](https://github.com/nlohmann/json/pull/400) ([andoma](https://github.com/andoma)) + +## [v2.0.9](https://github.com/nlohmann/json/releases/tag/v2.0.9) (2016-12-16) + +[Full Changelog](https://github.com/nlohmann/json/compare/2.0.9...v2.0.9) + +## [2.0.9](https://github.com/nlohmann/json/releases/tag/2.0.9) (2016-12-16) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.8...2.0.9) + +- \#pragma GCC diagnostic ignored "-Wdocumentation" [\#393](https://github.com/nlohmann/json/issues/393) +- How to parse this json file and write separate sub object as json files? [\#392](https://github.com/nlohmann/json/issues/392) +- Integer-overflow \(OSS-Fuzz issue 267\) [\#389](https://github.com/nlohmann/json/issues/389) +- Implement indefinite-length types from RFC 7049 [\#387](https://github.com/nlohmann/json/issues/387) +- template parameter "T" is not used in declaring the parameter types of function template [\#386](https://github.com/nlohmann/json/issues/386) +- Serializing json instances containing already serialized string values without escaping [\#385](https://github.com/nlohmann/json/issues/385) +- Add test cases from RFC 7049 [\#384](https://github.com/nlohmann/json/issues/384) +- Add a table of contents to the README file [\#383](https://github.com/nlohmann/json/issues/383) +- Update FAQ section in the guidelines for contributing [\#382](https://github.com/nlohmann/json/issues/382) +- Allow for forward declaring nlohmann::json [\#381](https://github.com/nlohmann/json/issues/381) +- Bug in overflow detection when parsing integers [\#380](https://github.com/nlohmann/json/issues/380) +- A unique name to mention the library? [\#377](https://github.com/nlohmann/json/issues/377) +- Non-unique keys in objects. [\#375](https://github.com/nlohmann/json/issues/375) +- Request: binary serialization/deserialization [\#358](https://github.com/nlohmann/json/issues/358) + +- Replace class iterator and const\_iterator by using a single template class to reduce code. [\#395](https://github.com/nlohmann/json/pull/395) ([Bosswestfalen](https://github.com/Bosswestfalen)) +- Clang: quiet a warning [\#391](https://github.com/nlohmann/json/pull/391) ([jaredgrubb](https://github.com/jaredgrubb)) +- Fix issue \#380: Signed integer overflow check [\#390](https://github.com/nlohmann/json/pull/390) ([qwename](https://github.com/qwename)) + +## [v2.0.8](https://github.com/nlohmann/json/releases/tag/v2.0.8) (2016-12-02) + +[Full Changelog](https://github.com/nlohmann/json/compare/2.0.8...v2.0.8) + +## [2.0.8](https://github.com/nlohmann/json/releases/tag/2.0.8) (2016-12-02) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.7...2.0.8) + +- Reading from file [\#374](https://github.com/nlohmann/json/issues/374) +- Compiler warnings? [\#372](https://github.com/nlohmann/json/issues/372) +- docs: how to release a json object in memory? [\#371](https://github.com/nlohmann/json/issues/371) +- crash in dump [\#370](https://github.com/nlohmann/json/issues/370) +- Coverity issue \(FORWARD\_NULL\) in lexer\(std::istream& s\) [\#368](https://github.com/nlohmann/json/issues/368) +- json::parse on failed stream gets stuck [\#366](https://github.com/nlohmann/json/issues/366) +- Performance improvements [\#365](https://github.com/nlohmann/json/issues/365) +- 'to\_string' is not a member of 'std' [\#364](https://github.com/nlohmann/json/issues/364) +- Crash in dump\(\) from a static object [\#359](https://github.com/nlohmann/json/issues/359) +- json::parse\(...\) vs json j; j.parse\(...\) [\#357](https://github.com/nlohmann/json/issues/357) +- Hi, is there any method to dump json to string with the insert order rather than alphabets [\#356](https://github.com/nlohmann/json/issues/356) +- Provide an example of reading from an json with only a key that has an array of strings. [\#354](https://github.com/nlohmann/json/issues/354) +- Request: access with default value. [\#353](https://github.com/nlohmann/json/issues/353) +- {} and \[\] causes parser error. [\#352](https://github.com/nlohmann/json/issues/352) +- Reading a JSON file into a JSON object [\#351](https://github.com/nlohmann/json/issues/351) +- Request: 'emplace\_back' [\#349](https://github.com/nlohmann/json/issues/349) +- Is it possible to stream data through the json parser without storing everything in memory? [\#347](https://github.com/nlohmann/json/issues/347) +- pure virtual conversion operator [\#346](https://github.com/nlohmann/json/issues/346) +- Floating point precision lost [\#345](https://github.com/nlohmann/json/issues/345) +- unit-conversions SIGSEGV on armv7hl [\#303](https://github.com/nlohmann/json/issues/303) +- Coverity scan fails [\#299](https://github.com/nlohmann/json/issues/299) +- Using QString as string type [\#274](https://github.com/nlohmann/json/issues/274) + +## [v2.0.7](https://github.com/nlohmann/json/releases/tag/v2.0.7) (2016-11-02) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.6...v2.0.7) + +- JSON5 [\#348](https://github.com/nlohmann/json/issues/348) +- Check "Parsing JSON is a Minefield" [\#344](https://github.com/nlohmann/json/issues/344) +- Allow hex numbers [\#342](https://github.com/nlohmann/json/issues/342) +- Convert strings to numbers [\#341](https://github.com/nlohmann/json/issues/341) +- ""-operators ignore the length parameter [\#340](https://github.com/nlohmann/json/issues/340) +- JSON into std::tuple [\#339](https://github.com/nlohmann/json/issues/339) +- JSON into vector [\#335](https://github.com/nlohmann/json/issues/335) +- Installing with Homebrew on Mac Errors \(El Capitan\) [\#331](https://github.com/nlohmann/json/issues/331) +- g++ make check results in error [\#312](https://github.com/nlohmann/json/issues/312) +- Cannot convert from 'json' to 'char' [\#276](https://github.com/nlohmann/json/issues/276) +- Please add a Pretty-Print option for arrays to stay always in one line [\#229](https://github.com/nlohmann/json/issues/229) +- Conversion to STL map\\> gives error [\#220](https://github.com/nlohmann/json/issues/220) +- std::unorderd\_map cannot be used as ObjectType [\#164](https://github.com/nlohmann/json/issues/164) + +- fix minor grammar/style issue in README.md [\#336](https://github.com/nlohmann/json/pull/336) ([seeekr](https://github.com/seeekr)) + +## [v2.0.6](https://github.com/nlohmann/json/releases/tag/v2.0.6) (2016-10-15) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.5...v2.0.6) + +- How to handle json files? [\#333](https://github.com/nlohmann/json/issues/333) +- This file requires compiler and library support .... [\#332](https://github.com/nlohmann/json/issues/332) +- Segmentation fault on saving json to file [\#326](https://github.com/nlohmann/json/issues/326) +- parse error - unexpected \ with 2.0.5 [\#325](https://github.com/nlohmann/json/issues/325) +- Add nested object capability to pointers [\#323](https://github.com/nlohmann/json/issues/323) +- Fix usage examples' comments for std::multiset [\#322](https://github.com/nlohmann/json/issues/322) +- json\_unit runs forever when executed in build directory [\#319](https://github.com/nlohmann/json/issues/319) +- Visual studio 2015 update3 true != TRUE [\#317](https://github.com/nlohmann/json/issues/317) +- releasing single header file in compressed format [\#316](https://github.com/nlohmann/json/issues/316) +- json object from std::ifstream [\#315](https://github.com/nlohmann/json/issues/315) + +- make has\_mapped\_type struct friendly [\#324](https://github.com/nlohmann/json/pull/324) ([vpetrigo](https://github.com/vpetrigo)) +- Fix usage examples' comments for std::multiset [\#321](https://github.com/nlohmann/json/pull/321) ([vasild](https://github.com/vasild)) +- Include dir relocation [\#318](https://github.com/nlohmann/json/pull/318) ([ChristophJud](https://github.com/ChristophJud)) +- trivial documentation fix [\#313](https://github.com/nlohmann/json/pull/313) ([5tefan](https://github.com/5tefan)) + +## [v2.0.5](https://github.com/nlohmann/json/releases/tag/v2.0.5) (2016-09-14) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.4...v2.0.5) + +- \[feature request\]: schema validator and comments [\#311](https://github.com/nlohmann/json/issues/311) +- make json\_benchmarks no longer working in 2.0.4 [\#310](https://github.com/nlohmann/json/issues/310) +- Segmentation fault \(core dumped\) [\#309](https://github.com/nlohmann/json/issues/309) +- No matching member function for call to 'get\_impl' [\#308](https://github.com/nlohmann/json/issues/308) + +## [v2.0.4](https://github.com/nlohmann/json/releases/tag/v2.0.4) (2016-09-11) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.3...v2.0.4) + +- Parsing fails without space at end of file [\#306](https://github.com/nlohmann/json/issues/306) +- json schema validator [\#305](https://github.com/nlohmann/json/issues/305) +- Unused variable warning [\#304](https://github.com/nlohmann/json/issues/304) + +## [v2.0.3](https://github.com/nlohmann/json/releases/tag/v2.0.3) (2016-08-31) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.2...v2.0.3) + +- warning C4706: assignment within conditional expression [\#295](https://github.com/nlohmann/json/issues/295) +- Q: Is it possible to build json tree from already UTF8 encoded values? [\#293](https://github.com/nlohmann/json/issues/293) +- Equality operator results in array when assigned object [\#292](https://github.com/nlohmann/json/issues/292) +- Support for integers not from the range \[-\(2\*\*53\)+1, \(2\*\*53\)-1\] in parser [\#291](https://github.com/nlohmann/json/issues/291) +- Support for iterator-range parsing [\#290](https://github.com/nlohmann/json/issues/290) +- Horribly inconsistent behavior between const/non-const reference in operator \[\] \(\) [\#289](https://github.com/nlohmann/json/issues/289) +- Silently get numbers into smaller types [\#288](https://github.com/nlohmann/json/issues/288) +- Incorrect parsing of large int64\_t numbers [\#287](https://github.com/nlohmann/json/issues/287) +- \[question\]: macro to disable floating point support [\#284](https://github.com/nlohmann/json/issues/284) + +- unit-constructor1.cpp: Fix floating point truncation warning [\#300](https://github.com/nlohmann/json/pull/300) ([t-b](https://github.com/t-b)) + +## [v2.0.2](https://github.com/nlohmann/json/releases/tag/v2.0.2) (2016-07-31) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.1...v2.0.2) + +- can function dump\(\) return string in the order I push in the json object ? [\#286](https://github.com/nlohmann/json/issues/286) +- Error on the Mac: Undefined symbols for architecture x86\_64 [\#285](https://github.com/nlohmann/json/issues/285) +- value\(\) does not work with \_json\_pointer types [\#283](https://github.com/nlohmann/json/issues/283) +- Build error for std::int64 [\#282](https://github.com/nlohmann/json/issues/282) +- strings can't be accessed after dump\(\)-\>parse\(\) - type is lost [\#281](https://github.com/nlohmann/json/issues/281) +- Easy serialization of classes [\#280](https://github.com/nlohmann/json/issues/280) +- recursive data structures [\#277](https://github.com/nlohmann/json/issues/277) +- hexify\(\) function emits conversion warning [\#270](https://github.com/nlohmann/json/issues/270) + +- let the makefile choose the correct sed [\#279](https://github.com/nlohmann/json/pull/279) ([murinicanor](https://github.com/murinicanor)) +- Update hexify to use array lookup instead of ternary \(\#270\) [\#275](https://github.com/nlohmann/json/pull/275) ([dtoma](https://github.com/dtoma)) + +## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28) + +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1) + +- Compilation error. [\#273](https://github.com/nlohmann/json/issues/273) +- dump\(\) performance degradation in v2 [\#272](https://github.com/nlohmann/json/issues/272) + +- fixed a tiny typo [\#271](https://github.com/nlohmann/json/pull/271) ([feroldi](https://github.com/feroldi)) + +## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23) + +[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...v2.0.0) + +- json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269) +- Docs - What does Json\[key\] return? [\#267](https://github.com/nlohmann/json/issues/267) +- Compiler Errors With JSON.hpp [\#265](https://github.com/nlohmann/json/issues/265) +- Ambiguous push\_back and operator+= overloads [\#263](https://github.com/nlohmann/json/issues/263) +- Preseving order of items in json [\#262](https://github.com/nlohmann/json/issues/262) +- '\' char problem in strings [\#261](https://github.com/nlohmann/json/issues/261) +- VS2015 compile fail [\#260](https://github.com/nlohmann/json/issues/260) +- -Wconversion warning [\#259](https://github.com/nlohmann/json/issues/259) +- Maybe a bug [\#258](https://github.com/nlohmann/json/issues/258) +- Few tests failed on Visual C++ 2015 [\#257](https://github.com/nlohmann/json/issues/257) +- Access keys when iteration with new for loop C++11 [\#256](https://github.com/nlohmann/json/issues/256) +- multiline text values [\#255](https://github.com/nlohmann/json/issues/255) +- Error when using json in g++ [\#254](https://github.com/nlohmann/json/issues/254) +- is the release 2.0? [\#253](https://github.com/nlohmann/json/issues/253) +- concatenate objects [\#252](https://github.com/nlohmann/json/issues/252) +- Encoding [\#251](https://github.com/nlohmann/json/issues/251) +- Unable to build example for constructing json object with stringstreams [\#250](https://github.com/nlohmann/json/issues/250) +- Hexadecimal support [\#249](https://github.com/nlohmann/json/issues/249) +- Update long-term goals [\#246](https://github.com/nlohmann/json/issues/246) +- Contribution To This Json Project [\#245](https://github.com/nlohmann/json/issues/245) +- Trouble using parser with initial dictionary [\#243](https://github.com/nlohmann/json/issues/243) +- Unit test fails when doing a CMake out-of-tree build [\#241](https://github.com/nlohmann/json/issues/241) +- -Wconversion warnings [\#239](https://github.com/nlohmann/json/issues/239) +- Additional integration options [\#237](https://github.com/nlohmann/json/issues/237) +- .get\\(\) works for non spaced string but returns as array for spaced/longer strings [\#236](https://github.com/nlohmann/json/issues/236) +- ambiguous overload for 'push\_back' and 'operator+=' [\#235](https://github.com/nlohmann/json/issues/235) +- Can't use basic\_json::iterator as a base iterator for std::move\_iterator [\#233](https://github.com/nlohmann/json/issues/233) +- json object's creation can freezes execution [\#231](https://github.com/nlohmann/json/issues/231) +- Incorrect dumping of parsed numbers with exponents, but without decimal places [\#230](https://github.com/nlohmann/json/issues/230) +- double values are serialized with commas as decimal points [\#228](https://github.com/nlohmann/json/issues/228) +- Move semantics with std::initializer\_list [\#225](https://github.com/nlohmann/json/issues/225) +- replace emplace [\#224](https://github.com/nlohmann/json/issues/224) +- abort during getline in yyfill [\#223](https://github.com/nlohmann/json/issues/223) +- free\(\): invalid pointer error in GCC 5.2.1 [\#221](https://github.com/nlohmann/json/issues/221) +- Error compile Android NDK error: 'strtof' is not a member of 'std' [\#219](https://github.com/nlohmann/json/issues/219) +- Wrong link in the README.md [\#217](https://github.com/nlohmann/json/issues/217) +- Wide character strings not supported [\#216](https://github.com/nlohmann/json/issues/216) +- Memory allocations using range-based for loops [\#214](https://github.com/nlohmann/json/issues/214) +- would you like to support gcc 4.8.1? [\#211](https://github.com/nlohmann/json/issues/211) +- Reading concatenated json's from an istream [\#210](https://github.com/nlohmann/json/issues/210) +- Conflicting typedef of ssize\_t on Windows 32 bit when using Boost.Python [\#204](https://github.com/nlohmann/json/issues/204) +- Inconsistency between operator\[\] and push\_back [\#203](https://github.com/nlohmann/json/issues/203) +- Small bugs in json.hpp \(get\_number\) and unit.cpp \(non-standard integer type test\) [\#199](https://github.com/nlohmann/json/issues/199) +- GCC/clang floating point parsing bug in strtod\(\) [\#195](https://github.com/nlohmann/json/issues/195) +- What is within scope? [\#192](https://github.com/nlohmann/json/issues/192) +- Bugs in miloyip/nativejson-benchmark: roundtrips [\#187](https://github.com/nlohmann/json/issues/187) +- Floating point exceptions [\#181](https://github.com/nlohmann/json/issues/181) +- Integer conversion to unsigned [\#178](https://github.com/nlohmann/json/issues/178) +- map string string fails to compile [\#176](https://github.com/nlohmann/json/issues/176) +- In basic\_json::basic\_json\(const CompatibleArrayType& val\), the requirement of CompatibleArrayType is not strict enough. [\#174](https://github.com/nlohmann/json/issues/174) +- Provide a FAQ [\#163](https://github.com/nlohmann/json/issues/163) +- Implicit assignment to std::string fails [\#144](https://github.com/nlohmann/json/issues/144) + +- Fix Issue \#265 [\#266](https://github.com/nlohmann/json/pull/266) ([06needhamt](https://github.com/06needhamt)) +- Define CMake/CTest tests [\#247](https://github.com/nlohmann/json/pull/247) ([robertmrk](https://github.com/robertmrk)) +- Out of tree builds and a few other miscellaneous CMake cleanups. [\#242](https://github.com/nlohmann/json/pull/242) ([ChrisKitching](https://github.com/ChrisKitching)) +- Implement additional integration options [\#238](https://github.com/nlohmann/json/pull/238) ([robertmrk](https://github.com/robertmrk)) +- make serialization locale-independent [\#232](https://github.com/nlohmann/json/pull/232) ([nlohmann](https://github.com/nlohmann)) +- fixes \#223 by updating README.md [\#227](https://github.com/nlohmann/json/pull/227) ([kevin--](https://github.com/kevin--)) +- Use namespace std for int64\_t and uint64\_t [\#226](https://github.com/nlohmann/json/pull/226) ([lv-zheng](https://github.com/lv-zheng)) +- Added missing cerrno header to fix ERANGE compile error on android [\#222](https://github.com/nlohmann/json/pull/222) ([Teemperor](https://github.com/Teemperor)) +- Corrected readme [\#218](https://github.com/nlohmann/json/pull/218) ([Annihil](https://github.com/Annihil)) +- Create PULL\_REQUEST\_TEMPLATE.md [\#213](https://github.com/nlohmann/json/pull/213) ([whackashoe](https://github.com/whackashoe)) +- fixed noexcept; added constexpr [\#208](https://github.com/nlohmann/json/pull/208) ([nlohmann](https://github.com/nlohmann)) +- Add support for afl-fuzz testing [\#207](https://github.com/nlohmann/json/pull/207) ([mykter](https://github.com/mykter)) +- replaced ssize\_t occurrences with auto \(addresses \#204\) [\#205](https://github.com/nlohmann/json/pull/205) ([nlohmann](https://github.com/nlohmann)) +- Fixed issue \#199 - Small bugs in json.hpp \(get\_number\) and unit.cpp \(non-standard integer type test\) [\#200](https://github.com/nlohmann/json/pull/200) ([twelsby](https://github.com/twelsby)) +- Fix broken link [\#197](https://github.com/nlohmann/json/pull/197) ([vog](https://github.com/vog)) +- Issue \#195 - update Travis to Trusty due to gcc/clang strtod\(\) bug [\#196](https://github.com/nlohmann/json/pull/196) ([twelsby](https://github.com/twelsby)) +- Issue \#178 - Extending support to full uint64\_t/int64\_t range and unsigned type \(updated\) [\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby)) + +## [v1.1.0](https://github.com/nlohmann/json/releases/tag/v1.1.0) (2016-01-24) + +[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0) + +- Small error in pull \#185 [\#194](https://github.com/nlohmann/json/issues/194) +- Bugs in miloyip/nativejson-benchmark: floating-point parsing [\#186](https://github.com/nlohmann/json/issues/186) +- Floating point equality [\#185](https://github.com/nlohmann/json/issues/185) +- Unused variables in catch [\#180](https://github.com/nlohmann/json/issues/180) +- Typo in documentation [\#179](https://github.com/nlohmann/json/issues/179) +- JSON performance benchmark comparision [\#177](https://github.com/nlohmann/json/issues/177) +- Since re2c is often ignored in pull requests, it may make sense to make a contributing.md file [\#175](https://github.com/nlohmann/json/issues/175) +- Question about exceptions [\#173](https://github.com/nlohmann/json/issues/173) +- Android? [\#172](https://github.com/nlohmann/json/issues/172) +- Cannot index by key of type static constexpr const char\* [\#171](https://github.com/nlohmann/json/issues/171) +- Add assertions [\#168](https://github.com/nlohmann/json/issues/168) +- MSVC 2015 build fails when attempting to compare object\_t [\#167](https://github.com/nlohmann/json/issues/167) +- Member detector is not portable [\#166](https://github.com/nlohmann/json/issues/166) +- Unnecessary const\_cast [\#162](https://github.com/nlohmann/json/issues/162) +- Question about get\_ref\(\) [\#128](https://github.com/nlohmann/json/issues/128) +- range based for loop for objects [\#83](https://github.com/nlohmann/json/issues/83) +- Consider submitting this to the Boost Library Incubator [\#66](https://github.com/nlohmann/json/issues/66) + +- Fixed Issue \#186 - add strto\(f|d|ld\) overload wrappers, "-0.0" special case and FP trailing zero [\#191](https://github.com/nlohmann/json/pull/191) ([twelsby](https://github.com/twelsby)) +- Issue \#185 - remove approx\(\) and use \#pragma to kill warnings [\#190](https://github.com/nlohmann/json/pull/190) ([twelsby](https://github.com/twelsby)) +- Fixed Issue \#171 - added two extra template overloads of operator\[\] for T\* arguments [\#189](https://github.com/nlohmann/json/pull/189) ([twelsby](https://github.com/twelsby)) +- Fixed issue \#167 - removed operator ValueType\(\) condition for VS2015 [\#188](https://github.com/nlohmann/json/pull/188) ([twelsby](https://github.com/twelsby)) +- Implementation of get\_ref\(\) [\#184](https://github.com/nlohmann/json/pull/184) ([dariomt](https://github.com/dariomt)) +- Fixed some typos in CONTRIBUTING.md [\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc)) + +## [v1.0.0](https://github.com/nlohmann/json/releases/tag/v1.0.0) (2015-12-27) + +[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0) + +- add key name to exception [\#160](https://github.com/nlohmann/json/issues/160) +- Getting member discarding qualifyer [\#159](https://github.com/nlohmann/json/issues/159) +- basic\_json::iterator::value\(\) output includes quotes while basic\_json::iterator::key\(\) doesn't [\#158](https://github.com/nlohmann/json/issues/158) +- Indexing `const basic_json<>` with `const basic_string` [\#157](https://github.com/nlohmann/json/issues/157) +- token\_type\_name\(token\_type t\): not all control paths return a value [\#156](https://github.com/nlohmann/json/issues/156) +- prevent json.hpp from emitting compiler warnings [\#154](https://github.com/nlohmann/json/issues/154) +- json::parse\(string\) does not check utf8 bom [\#152](https://github.com/nlohmann/json/issues/152) +- unsigned 64bit values output as signed [\#151](https://github.com/nlohmann/json/issues/151) +- Wish feature: json5 [\#150](https://github.com/nlohmann/json/issues/150) +- Unable to compile on MSVC 2015 with SDL checking enabled: This function or variable may be unsafe. [\#149](https://github.com/nlohmann/json/issues/149) +- "Json Object" type does not keep object order [\#148](https://github.com/nlohmann/json/issues/148) +- dump\(\) convert strings encoded by utf-8 to shift-jis on windows 10. [\#147](https://github.com/nlohmann/json/issues/147) +- Unable to get field names in a json object [\#145](https://github.com/nlohmann/json/issues/145) +- Question: Is the use of incomplete type correct? [\#138](https://github.com/nlohmann/json/issues/138) +- json.hpp:5746:32: error: 'to\_string' is not a member of 'std' [\#136](https://github.com/nlohmann/json/issues/136) +- Bug in basic\_json::operator\[\] const overload [\#135](https://github.com/nlohmann/json/issues/135) +- wrong enable\_if for const pointer \(instead of pointer-to-const\) [\#134](https://github.com/nlohmann/json/issues/134) +- overload of at\(\) with default value [\#133](https://github.com/nlohmann/json/issues/133) +- Splitting source [\#132](https://github.com/nlohmann/json/issues/132) +- Question about get\_ptr\(\) [\#127](https://github.com/nlohmann/json/issues/127) +- Visual Studio 14 Debug assertion failed [\#125](https://github.com/nlohmann/json/issues/125) +- Memory leak in face of exceptions [\#118](https://github.com/nlohmann/json/issues/118) +- Find and Count for arrays [\#117](https://github.com/nlohmann/json/issues/117) +- dynamically constructing an arbitrarily nested object [\#114](https://github.com/nlohmann/json/issues/114) +- Returning any data type [\#113](https://github.com/nlohmann/json/issues/113) +- Compile error with g++ 4.9.3 cygwin 64-bit [\#112](https://github.com/nlohmann/json/issues/112) +- insert json array issue with gcc4.8.2 [\#110](https://github.com/nlohmann/json/issues/110) +- error: unterminated raw string [\#109](https://github.com/nlohmann/json/issues/109) +- vector\ copy constructor really weird [\#108](https://github.com/nlohmann/json/issues/108) +- \[clang-3.6.2\] string/sstream with number to json issue [\#107](https://github.com/nlohmann/json/issues/107) +- object field accessors [\#103](https://github.com/nlohmann/json/issues/103) +- v8pp and json [\#95](https://github.com/nlohmann/json/issues/95) +- Wishlist [\#65](https://github.com/nlohmann/json/issues/65) +- Windows/Visual Studio \(through 2013\) is unsupported [\#62](https://github.com/nlohmann/json/issues/62) + +- Replace sprintf with hex function, this fixes \#149 [\#153](https://github.com/nlohmann/json/pull/153) ([whackashoe](https://github.com/whackashoe)) +- Fix character skipping after a surrogate pair [\#146](https://github.com/nlohmann/json/pull/146) ([robertmrk](https://github.com/robertmrk)) +- Detect correctly pointer-to-const [\#137](https://github.com/nlohmann/json/pull/137) ([dariomt](https://github.com/dariomt)) +- disabled "CopyAssignable" test for MSVC in Debug mode, see \#125 [\#131](https://github.com/nlohmann/json/pull/131) ([dariomt](https://github.com/dariomt)) +- removed stream operator for iterator, resolution for \#125 [\#130](https://github.com/nlohmann/json/pull/130) ([dariomt](https://github.com/dariomt)) +- fixed typos in comments for examples [\#129](https://github.com/nlohmann/json/pull/129) ([dariomt](https://github.com/dariomt)) +- Remove superfluous inefficiency [\#126](https://github.com/nlohmann/json/pull/126) ([d-frey](https://github.com/d-frey)) +- remove invalid parameter '-stdlib=libc++' in CMakeLists.txt [\#124](https://github.com/nlohmann/json/pull/124) ([emvivre](https://github.com/emvivre)) +- exception-safe object creation, fixes \#118 [\#122](https://github.com/nlohmann/json/pull/122) ([d-frey](https://github.com/d-frey)) +- Fix small oversight. [\#121](https://github.com/nlohmann/json/pull/121) ([ColinH](https://github.com/ColinH)) +- Overload parse\(\) to accept an rvalue reference [\#120](https://github.com/nlohmann/json/pull/120) ([silverweed](https://github.com/silverweed)) +- Use the right variable name in doc string [\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu)) + +## [v1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1) (2015-07-26) + +[Full Changelog](https://github.com/nlohmann/json/compare/4502e7e51c0569419c26e75fbdd5748170603e54...v1.0.0-rc1) + +- Finish documenting the public interface in Doxygen [\#102](https://github.com/nlohmann/json/issues/102) +- Binary string causes numbers to be dumped as hex [\#101](https://github.com/nlohmann/json/issues/101) +- failed to iterator json object with reverse\_iterator [\#100](https://github.com/nlohmann/json/issues/100) +- 'noexcept' : unknown override specifier [\#99](https://github.com/nlohmann/json/issues/99) +- json float parsing problem [\#98](https://github.com/nlohmann/json/issues/98) +- Adjust wording to JSON RFC [\#97](https://github.com/nlohmann/json/issues/97) +- static analysis warnings [\#94](https://github.com/nlohmann/json/issues/94) +- reverse\_iterator operator inheritance problem [\#93](https://github.com/nlohmann/json/issues/93) +- init error [\#92](https://github.com/nlohmann/json/issues/92) +- access by \(const\) reference [\#91](https://github.com/nlohmann/json/issues/91) +- is\_integer and is\_float tests [\#90](https://github.com/nlohmann/json/issues/90) +- Nonstandard integer type [\#89](https://github.com/nlohmann/json/issues/89) +- static library build [\#84](https://github.com/nlohmann/json/issues/84) +- lexer::get\_number return NAN [\#82](https://github.com/nlohmann/json/issues/82) +- MinGW have no std::to\_string [\#80](https://github.com/nlohmann/json/issues/80) +- Incorrect behaviour of basic\_json::count method [\#78](https://github.com/nlohmann/json/issues/78) +- Invoking is\_array\(\) function creates "null" value [\#77](https://github.com/nlohmann/json/issues/77) +- dump\(\) / parse\(\) not idempotent [\#76](https://github.com/nlohmann/json/issues/76) +- Handle infinity and NaN cases [\#70](https://github.com/nlohmann/json/issues/70) +- errors in g++-4.8.1 [\#68](https://github.com/nlohmann/json/issues/68) +- Keys when iterating over objects [\#67](https://github.com/nlohmann/json/issues/67) +- Compilation results in tons of warnings [\#64](https://github.com/nlohmann/json/issues/64) +- Complete brief documentation [\#61](https://github.com/nlohmann/json/issues/61) +- Double quotation mark is not parsed correctly [\#60](https://github.com/nlohmann/json/issues/60) +- Get coverage back to 100% [\#58](https://github.com/nlohmann/json/issues/58) +- erase elements using iterators [\#57](https://github.com/nlohmann/json/issues/57) +- Removing item from array [\#56](https://github.com/nlohmann/json/issues/56) +- Serialize/Deserialize like PHP? [\#55](https://github.com/nlohmann/json/issues/55) +- Numbers as keys [\#54](https://github.com/nlohmann/json/issues/54) +- Why are elements alphabetized on key while iterating? [\#53](https://github.com/nlohmann/json/issues/53) +- Document erase, count, and iterators key and value [\#52](https://github.com/nlohmann/json/issues/52) +- Do not use std::to\_string [\#51](https://github.com/nlohmann/json/issues/51) +- Supported compilers [\#50](https://github.com/nlohmann/json/issues/50) +- Confused about iterating through json objects [\#49](https://github.com/nlohmann/json/issues/49) +- Use non-member begin/end [\#48](https://github.com/nlohmann/json/issues/48) +- Erase key [\#47](https://github.com/nlohmann/json/issues/47) +- Key iterator [\#46](https://github.com/nlohmann/json/issues/46) +- Add count member function [\#45](https://github.com/nlohmann/json/issues/45) +- Problem getting vector \(array\) of strings [\#44](https://github.com/nlohmann/json/issues/44) +- Compilation error due to assuming that private=public [\#43](https://github.com/nlohmann/json/issues/43) +- Use of deprecated implicit copy constructor [\#42](https://github.com/nlohmann/json/issues/42) +- Printing attribute names [\#39](https://github.com/nlohmann/json/issues/39) +- dumping a small number\_float just outputs 0.000000 [\#37](https://github.com/nlohmann/json/issues/37) +- find is error [\#32](https://github.com/nlohmann/json/issues/32) +- Avoid using spaces when encoding without pretty print [\#31](https://github.com/nlohmann/json/issues/31) +- Cannot encode long numbers [\#30](https://github.com/nlohmann/json/issues/30) +- segmentation fault when iterating over empty arrays/objects [\#28](https://github.com/nlohmann/json/issues/28) +- Creating an empty array [\#27](https://github.com/nlohmann/json/issues/27) +- Custom allocator support [\#25](https://github.com/nlohmann/json/issues/25) +- make the type of the used string container customizable [\#20](https://github.com/nlohmann/json/issues/20) +- Improper parsing of JSON string "\\" [\#17](https://github.com/nlohmann/json/issues/17) +- create a header-only version [\#16](https://github.com/nlohmann/json/issues/16) +- Don't return "const values" [\#15](https://github.com/nlohmann/json/issues/15) +- Add to\_string overload for indentation [\#13](https://github.com/nlohmann/json/issues/13) +- string parser does not recognize uncompliant strings [\#12](https://github.com/nlohmann/json/issues/12) +- possible double-free in find function [\#11](https://github.com/nlohmann/json/issues/11) +- UTF-8 encoding/deconding/testing [\#10](https://github.com/nlohmann/json/issues/10) +- move code into namespace [\#9](https://github.com/nlohmann/json/issues/9) +- free functions for explicit objects and arrays in initializer lists [\#8](https://github.com/nlohmann/json/issues/8) +- unique\_ptr for ownership [\#7](https://github.com/nlohmann/json/issues/7) +- Add unit tests [\#4](https://github.com/nlohmann/json/issues/4) +- Drop C++98 support [\#3](https://github.com/nlohmann/json/issues/3) +- Test case coverage [\#2](https://github.com/nlohmann/json/issues/2) +- Runtime error in Travis job [\#1](https://github.com/nlohmann/json/issues/1) + +- Keyword 'inline' is useless when member functions are defined in headers [\#87](https://github.com/nlohmann/json/pull/87) ([ahamez](https://github.com/ahamez)) +- Remove useless typename [\#86](https://github.com/nlohmann/json/pull/86) ([ahamez](https://github.com/ahamez)) +- Avoid warning with Xcode's clang [\#85](https://github.com/nlohmann/json/pull/85) ([ahamez](https://github.com/ahamez)) +- Fix typos [\#73](https://github.com/nlohmann/json/pull/73) ([aqnouch](https://github.com/aqnouch)) +- Replace `default_callback` function with `nullptr` and check for null… [\#72](https://github.com/nlohmann/json/pull/72) ([aburgh](https://github.com/aburgh)) +- support enum [\#71](https://github.com/nlohmann/json/pull/71) ([likebeta](https://github.com/likebeta)) +- Fix performance regression introduced with the parsing callback feature. [\#69](https://github.com/nlohmann/json/pull/69) ([aburgh](https://github.com/aburgh)) +- Improve the implementations of the comparission-operators [\#63](https://github.com/nlohmann/json/pull/63) ([Florianjw](https://github.com/Florianjw)) +- Fix compilation of json\_unit with GCC 5 [\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek)) +- Parse streams incrementally. [\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh)) +- Feature/small float serialization [\#38](https://github.com/nlohmann/json/pull/38) ([jrandall](https://github.com/jrandall)) +- template version with re2c scanner [\#36](https://github.com/nlohmann/json/pull/36) ([nlohmann](https://github.com/nlohmann)) +- more descriptive documentation in example [\#33](https://github.com/nlohmann/json/pull/33) ([luxe](https://github.com/luxe)) +- Fix string conversion under Clang [\#26](https://github.com/nlohmann/json/pull/26) ([wancw](https://github.com/wancw)) +- Fixed dumping of strings [\#24](https://github.com/nlohmann/json/pull/24) ([Teemperor](https://github.com/Teemperor)) +- Added a remark to the readme that coverage is GCC only for now [\#23](https://github.com/nlohmann/json/pull/23) ([Teemperor](https://github.com/Teemperor)) +- Unicode escaping [\#22](https://github.com/nlohmann/json/pull/22) ([Teemperor](https://github.com/Teemperor)) +- Implemented the JSON spec for string parsing for everything but the \uXXXX escaping [\#21](https://github.com/nlohmann/json/pull/21) ([Teemperor](https://github.com/Teemperor)) +- add the std iterator typedefs to iterator and const\_iterator [\#19](https://github.com/nlohmann/json/pull/19) ([kirkshoop](https://github.com/kirkshoop)) +- Fixed escaped quotes [\#18](https://github.com/nlohmann/json/pull/18) ([Teemperor](https://github.com/Teemperor)) +- Fix double delete on std::bad\_alloc exception [\#14](https://github.com/nlohmann/json/pull/14) ([elliotgoodrich](https://github.com/elliotgoodrich)) +- Added CMake and lcov [\#6](https://github.com/nlohmann/json/pull/6) ([Teemperor](https://github.com/Teemperor)) +- Version 2.0 [\#5](https://github.com/nlohmann/json/pull/5) ([nlohmann](https://github.com/nlohmann)) + + + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* diff --git a/json-develop/LICENSE.MIT b/json-develop/LICENSE.MIT new file mode 100644 index 0000000..1c1f7a6 --- /dev/null +++ b/json-develop/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2022 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/json-develop/LICENSES/Apache-2.0.txt b/json-develop/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000..137069b --- /dev/null +++ b/json-develop/LICENSES/Apache-2.0.txt @@ -0,0 +1,73 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/json-develop/LICENSES/BSD-3-Clause.txt b/json-develop/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000..ea890af --- /dev/null +++ b/json-develop/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,11 @@ +Copyright (c) . + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/json-develop/LICENSES/GPL-3.0-only.txt b/json-develop/LICENSES/GPL-3.0-only.txt new file mode 100644 index 0000000..d41c0bd --- /dev/null +++ b/json-develop/LICENSES/GPL-3.0-only.txt @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/json-develop/LICENSES/MIT.txt b/json-develop/LICENSES/MIT.txt new file mode 100644 index 0000000..2071b23 --- /dev/null +++ b/json-develop/LICENSES/MIT.txt @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/json-develop/Makefile b/json-develop/Makefile new file mode 100644 index 0000000..6eff866 --- /dev/null +++ b/json-develop/Makefile @@ -0,0 +1,284 @@ +.PHONY: pretty clean ChangeLog.md release + +########################################################################## +# configuration +########################################################################## + +# find GNU sed to use `-i` parameter +SED:=$(shell command -v gsed || which sed) + + +########################################################################## +# source files +########################################################################## + +# the list of sources in the include folder +SRCS=$(shell find include -type f | sort) + +# the list of sources in the tests folder +TESTS_SRCS=$(shell find tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name '*.cu' \) -not -path 'tests/thirdparty/*' -not -path 'tests/abi/include/nlohmann/*' | sort) + +# the single headers (amalgamated from the source files) +AMALGAMATED_FILE=single_include/nlohmann/json.hpp +AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp + + +########################################################################## +# documentation of the Makefile's targets +########################################################################## + +# main target +all: + @echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd}.hpp from the include/nlohmann sources" + @echo "ChangeLog.md - generate ChangeLog file" + @echo "check-amalgamation - check whether sources have been amalgamated" + @echo "clean - remove built files" + @echo "doctest - compile example files and check their output" + @echo "fuzz_testing - prepare fuzz testing of the JSON parser" + @echo "fuzz_testing_bson - prepare fuzz testing of the BSON parser" + @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" + @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" + @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" + @echo "pretty - beautify code with Artistic Style" + @echo "run_benchmarks - build and run benchmarks" + + +########################################################################## +# documentation tests +########################################################################## + +# compile example files and check output +doctest: + $(MAKE) check_output -C docs + + +########################################################################## +# benchmarks +########################################################################## + +run_benchmarks: + rm -fr cmake-build-benchmarks + mkdir cmake-build-benchmarks + cd cmake-build-benchmarks ; cmake ../tests/benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release + cd cmake-build-benchmarks ; ninja + cd cmake-build-benchmarks ; ./json_benchmarks + + +########################################################################## +# fuzzing +########################################################################## + +# the overall fuzz testing target +fuzz_testing: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) parse_afl_fuzzer -C tests CXX=afl-clang++ + mv tests/parse_afl_fuzzer fuzz-testing/fuzzer + find tests/data/json_tests -size -5k -name *json | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + +fuzz_testing_bson: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) parse_bson_fuzzer -C tests CXX=afl-clang++ + mv tests/parse_bson_fuzzer fuzz-testing/fuzzer + find tests/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + +fuzz_testing_cbor: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) parse_cbor_fuzzer -C tests CXX=afl-clang++ + mv tests/parse_cbor_fuzzer fuzz-testing/fuzzer + find tests/data -size -5k -name *.cbor | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + +fuzz_testing_msgpack: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) parse_msgpack_fuzzer -C tests CXX=afl-clang++ + mv tests/parse_msgpack_fuzzer fuzz-testing/fuzzer + find tests/data -size -5k -name *.msgpack | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + +fuzz_testing_ubjson: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) parse_ubjson_fuzzer -C tests CXX=afl-clang++ + mv tests/parse_ubjson_fuzzer fuzz-testing/fuzzer + find tests/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + +fuzzing-start: + afl-fuzz -S fuzzer1 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -S fuzzer2 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -S fuzzer3 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -S fuzzer4 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -S fuzzer5 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -S fuzzer6 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -S fuzzer7 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & + afl-fuzz -M fuzzer0 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer + +fuzzing-stop: + -killall fuzzer + -killall afl-fuzz + + +########################################################################## +# Static analysis +########################################################################## + +# call PVS-Studio Analyzer +pvs_studio: + rm -fr cmake-build-pvs-studio + mkdir cmake-build-pvs-studio + cd cmake-build-pvs-studio ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON + cd cmake-build-pvs-studio ; pvs-studio-analyzer analyze -j 10 + cd cmake-build-pvs-studio ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs + open cmake-build-pvs-studio/pvs/index.html + + +########################################################################## +# Code format and source amalgamation +########################################################################## + +# call the Artistic Style pretty printer on all source files +pretty: + astyle \ + --style=allman \ + --indent=spaces=4 \ + --indent-modifiers \ + --indent-switches \ + --indent-preproc-block \ + --indent-preproc-define \ + --indent-col1-comments \ + --pad-oper \ + --pad-header \ + --align-pointer=type \ + --align-reference=type \ + --add-brackets \ + --convert-tabs \ + --close-templates \ + --lineend=linux \ + --preserve-date \ + --suffix=none \ + --formatted \ + $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) docs/examples/*.cpp + +# call the Clang-Format on all source files +pretty_format: + for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done + +# create single header files and pretty print +amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) + $(MAKE) pretty + +# call the amalgamation tool for json.hpp +$(AMALGAMATED_FILE): $(SRCS) + tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json.json -s . --verbose=yes + +# call the amalgamation tool for json_fwd.hpp +$(AMALGAMATED_FWD_FILE): $(SRCS) + tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_fwd.json -s . --verbose=yes + +# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources +# Note: this target is called by Travis +check-amalgamation: + @mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ + @mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ + @$(MAKE) amalgamate + @diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false) + @diff $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) ; false) + @mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) + @mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) + +BUILD.bazel: $(SRCS) + cmake -P cmake/scripts/gen_bazel_build_file.cmake + +########################################################################## +# ChangeLog +########################################################################## + +# Create a ChangeLog based on the git log using the GitHub Changelog Generator +# (). + +# variable to control the diffs between the last released version and the current repository state +NEXT_VERSION ?= "unreleased" + +ChangeLog.md: + github_changelog_generator -o ChangeLog.md --user nlohmann --project json --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s --future-release $(NEXT_VERSION) + $(SED) -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md + $(SED) -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md + + +########################################################################## +# Release files +########################################################################## + +# Create a tar.gz archive that contains sufficient files to be used as CMake project (e.g., using FetchContent). The +# archive is created according to the advices of . +json.tar.xz: + mkdir json + rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json + gtar --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz + rm -fr json + +# We use `-X` to make the resulting ZIP file reproducible, see +# . +include.zip: BUILD.bazel + zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) BUILD.bazel WORKSPACE.bazel meson.build LICENSE.MIT + +# Create the files for a release and add signatures and hashes. +release: include.zip json.tar.xz + rm -fr release_files + mkdir release_files + gpg --armor --detach-sig include.zip + gpg --armor --detach-sig $(AMALGAMATED_FILE) + gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE) + gpg --armor --detach-sig json.tar.xz + cp $(AMALGAMATED_FILE) release_files + cp $(AMALGAMATED_FWD_FILE) release_files + mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files + cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt + + +########################################################################## +# Maintenance +########################################################################## + +# clean up +clean: + rm -fr fuzz fuzz-testing *.dSYM tests/*.dSYM + rm -fr benchmarks/files/numbers/*.json + rm -fr cmake-build-benchmarks fuzz-testing cmake-build-pvs-studio release_files + $(MAKE) clean -Cdocs + + +########################################################################## +# Thirdparty code +########################################################################## + +update_hedley: + rm -f include/nlohmann/thirdparty/hedley/hedley.hpp include/nlohmann/thirdparty/hedley/hedley_undef.hpp + curl https://raw.githubusercontent.com/nemequ/hedley/master/hedley.h -o include/nlohmann/thirdparty/hedley/hedley.hpp + $(SED) -i 's/HEDLEY_/JSON_HEDLEY_/g' include/nlohmann/thirdparty/hedley/hedley.hpp + grep "[[:blank:]]*#[[:blank:]]*undef" include/nlohmann/thirdparty/hedley/hedley.hpp | grep -v "__" | sort | uniq | $(SED) 's/ //g' | $(SED) 's/undef/undef /g' > include/nlohmann/thirdparty/hedley/hedley_undef.hpp + $(SED) -i '1s/^/#pragma once\n\n/' include/nlohmann/thirdparty/hedley/hedley.hpp + $(SED) -i '1s/^/#pragma once\n\n/' include/nlohmann/thirdparty/hedley/hedley_undef.hpp + $(MAKE) amalgamate + +########################################################################## +# serve_header.py +########################################################################## + +serve_header: + ./tools/serve_header/serve_header.py --make $(MAKE) + +########################################################################## +# REUSE +########################################################################## + +reuse: + pipx run reuse addheader --recursive single_include include -tjson --license MIT --copyright "Niels Lohmann " --year "2013-2022" + pipx run reuse addheader $(TESTS_SRCS) --style=c -tjson_support --license MIT --copyright "Niels Lohmann " --year "2013-2022" + pipx run reuse lint diff --git a/json-develop/README.md b/json-develop/README.md new file mode 100644 index 0000000..acc16ea --- /dev/null +++ b/json-develop/README.md @@ -0,0 +1,1858 @@ +[![JSON for Modern C++](docs/json.gif)](https://github.com/nlohmann/json/releases) + +[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json) +[![Ubuntu](https://github.com/nlohmann/json/workflows/Ubuntu/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AUbuntu) +[![macOS](https://github.com/nlohmann/json/workflows/macOS/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AmacOS) +[![Windows](https://github.com/nlohmann/json/workflows/Windows/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AWindows) +[![Coverage Status](https://coveralls.io/repos/github/nlohmann/json/badge.svg?branch=develop)](https://coveralls.io/github/nlohmann/json?branch=develop) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/e0d1a9d5d6fd46fcb655c4cb930bb3e8)](https://www.codacy.com/gh/nlohmann/json/dashboard?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade) +[![Cirrus CI](https://api.cirrus-ci.com/github/nlohmann/json.svg)](https://cirrus-ci.com/github/nlohmann/json) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json) +[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/1mp10JbaANo6FUc7) +[![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://json.nlohmann.me) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) +[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases) +[![Vcpkg Version](https://img.shields.io/vcpkg/v/nlohmann-json)](https://vcpkg.link/ports/nlohmann-json) +[![Packaging status](https://repology.org/badge/tiny-repos/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) +[![GitHub Downloads](https://img.shields.io/github/downloads/nlohmann/json/total)](https://github.com/nlohmann/json/releases) +[![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](https://github.com/nlohmann/json/issues) +[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/nlohmann/json.svg)](https://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue") +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/289/badge)](https://bestpractices.coreinfrastructure.org/projects/289) +[![GitHub Sponsors](https://img.shields.io/badge/GitHub-Sponsors-ff69b4)](https://github.com/sponsors/nlohmann) +[![REUSE status](https://api.reuse.software/badge/github.com/nlohmann/json)](https://api.reuse.software/info/github.com/nlohmann/json) +[![Discord](https://img.shields.io/discord/1003743314341793913)](https://discord.gg/6mrGXKvX7y) + +- [Design goals](#design-goals) +- [Sponsors](#sponsors) +- [Support](#support) ([documentation](https://json.nlohmann.me), [FAQ](https://json.nlohmann.me/home/faq/), [discussions](https://github.com/nlohmann/json/discussions), [API](https://json.nlohmann.me/api/basic_json/), [bug issues](https://github.com/nlohmann/json/issues)) +- [Examples](#examples) + - [Read JSON from a file](#read-json-from-a-file) + - [Creating `json` objects from JSON literals](#creating-json-objects-from-json-literals) + - [JSON as first-class data type](#json-as-first-class-data-type) + - [Serialization / Deserialization](#serialization--deserialization) + - [STL-like access](#stl-like-access) + - [Conversion from STL containers](#conversion-from-stl-containers) + - [JSON Pointer and JSON Patch](#json-pointer-and-json-patch) + - [JSON Merge Patch](#json-merge-patch) + - [Implicit conversions](#implicit-conversions) + - [Conversions to/from arbitrary types](#arbitrary-types-conversions) + - [Specializing enum conversion](#specializing-enum-conversion) + - [Binary formats (BSON, CBOR, MessagePack, UBJSON, and BJData)](#binary-formats-bson-cbor-messagepack-ubjson-and-bjdata) +- [Supported compilers](#supported-compilers) +- [Integration](#integration) + - [CMake](#cmake) + - [Package Managers](#package-managers) + - [Pkg-config](#pkg-config) +- [License](#license) +- [Contact](#contact) +- [Thanks](#thanks) +- [Used third-party tools](#used-third-party-tools) +- [Projects using JSON for Modern C++](#projects-using-json-for-modern-c) +- [Notes](#notes) +- [Execute unit tests](#execute-unit-tests) + +## Design goals + +There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals: + +- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean. + +- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. + +- **Serious testing**. Our code is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/tests/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](https://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289). + +Other aspects were not so important to us: + +- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. + +- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. + +See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. + + +## Sponsors + +You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann). + +### :office: Corporate Sponsor + +[![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Codacy-logo-black.svg/320px-Codacy-logo-black.svg.png)](https://github.com/codacy/About) + +### :label: Named Sponsors + +- [Michael Hartmann](https://github.com/reFX-Mike) +- [Stefan Hagen](https://github.com/sthagen) +- [Steve Sperandeo](https://github.com/homer6) +- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe) +- [Steve Wagner](https://github.com/ciroque) + +Thanks everyone! + +## Support + +:question: If you have a **question**, please check if it is already answered in the [**FAQ**](https://json.nlohmann.me/home/faq/) or the [**Q&A**](https://github.com/nlohmann/json/discussions/categories/q-a) section. If not, please [**ask a new question**](https://github.com/nlohmann/json/discussions/new) there. + +:books: If you want to **learn more** about how to use the library, check out the rest of the [**README**](#examples), have a look at [**code examples**](https://github.com/nlohmann/json/tree/develop/docs/examples), or browse through the [**help pages**](https://json.nlohmann.me). + +:construction: If you want to understand the **API** better, check out the [**API Reference**](https://json.nlohmann.me/api/basic_json/). + +:bug: If you found a **bug**, please check the [**FAQ**](https://json.nlohmann.me/home/faq/) if it is a known issue or the result of a design decision. Please also have a look at the [**issue list**](https://github.com/nlohmann/json/issues) before you [**create a new issue**](https://github.com/nlohmann/json/issues/new/choose). Please provide as much information as possible to help us understand and reproduce your issue. + +There is also a [**docset**](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B) for the documentation browsers [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), and [Zeal](https://zealdocs.org) that contains the full [documentation](https://json.nlohmann.me) as offline resource. + +## Examples + +Here are some examples to give you an idea how to use the class. + +Beside the examples below, you may want to: + +→ Check the [documentation](https://json.nlohmann.me/)\ +→ Browse the [standalone example files](https://github.com/nlohmann/json/tree/develop/docs/examples) + +Every API function (documented in the [API Documentation](https://json.nlohmann.me/api/basic_json/)) has a corresponding standalone example file. For example, the [`emplace()`](https://json.nlohmann.me/api/basic_json/emplace/) function has a matching [emplace.cpp](https://github.com/nlohmann/json/blob/develop/docs/examples/emplace.cpp) example file. + +### Read JSON from a file + +The `json` class provides an API for manipulating a JSON value. To create a `json` object by reading a JSON file: + +```cpp +#include +#include +using json = nlohmann::json; + +// ... + +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +### Creating `json` objects from JSON literals + +Assume you want to create hard-code this literal JSON value in a file, as a `json` object: + +```json +{ + "pi": 3.141, + "happy": true +} +``` + +There are various options: + +```cpp +// Using (raw) string literals and json::parse +json ex1 = json::parse(R"( + { + "pi": 3.141, + "happy": true + } +)"); + +// Using user-defined (raw) string literals +using namespace nlohmann::literals; +json ex2 = R"( + { + "pi": 3.141, + "happy": true + } +)"_json; + +// Using initializer lists +json ex3 = { + {"happy", true}, + {"pi", 3.141}, +}; +``` + +### JSON as first-class data type + +Here are some examples to give you an idea how to use the class. + +Assume you want to create the JSON object + +```json +{ + "pi": 3.141, + "happy": true, + "name": "Niels", + "nothing": null, + "answer": { + "everything": 42 + }, + "list": [1, 0, 2], + "object": { + "currency": "USD", + "value": 42.99 + } +} +``` + +With this library, you could write: + +```cpp +// create an empty structure (null) +json j; + +// add a number that is stored as double (note the implicit conversion of j to an object) +j["pi"] = 3.141; + +// add a Boolean that is stored as bool +j["happy"] = true; + +// add a string that is stored as std::string +j["name"] = "Niels"; + +// add another null object by passing nullptr +j["nothing"] = nullptr; + +// add an object inside the object +j["answer"]["everything"] = 42; + +// add an array that is stored as std::vector (using an initializer list) +j["list"] = { 1, 0, 2 }; + +// add another object (using an initializer list of pairs) +j["object"] = { {"currency", "USD"}, {"value", 42.99} }; + +// instead, you could also write (which looks very similar to the JSON above) +json j2 = { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + {"answer", { + {"everything", 42} + }}, + {"list", {1, 0, 2}}, + {"object", { + {"currency", "USD"}, + {"value", 42.99} + }} +}; +``` + +Note that in all these cases, you never need to "tell" the compiler which JSON value type you want to use. If you want to be explicit or express some edge cases, the functions [`json::array()`](https://json.nlohmann.me/api/basic_json/array/) and [`json::object()`](https://json.nlohmann.me/api/basic_json/object/) will help: + +```cpp +// a way to express the empty array [] +json empty_array_explicit = json::array(); + +// ways to express the empty object {} +json empty_object_implicit = json({}); +json empty_object_explicit = json::object(); + +// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]] +json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} }); +``` + +### Serialization / Deserialization + +#### To/from strings + +You can create a JSON value (deserialization) by appending `_json` to a string literal: + +```cpp +// create object from string literal +json j = "{ \"happy\": true, \"pi\": 3.141 }"_json; + +// or even nicer with a raw string literal +auto j2 = R"( + { + "happy": true, + "pi": 3.141 + } +)"_json; +``` + +Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string +value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string +`"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object. + +The string literal should be brought into scope with `using namespace nlohmann::literals;` +(see [`json::parse()`](https://json.nlohmann.me/api/operator_literal_json/)). + +The above example can also be expressed explicitly using [`json::parse()`](https://json.nlohmann.me/api/basic_json/parse/): + +```cpp +// parse explicitly +auto j3 = json::parse(R"({"happy": true, "pi": 3.141})"); +``` + +You can also get a string representation of a JSON value (serialize): + +```cpp +// explicit conversion to string +std::string s = j.dump(); // {"happy":true,"pi":3.141} + +// serialization with pretty printing +// pass in the amount of spaces to indent +std::cout << j.dump(4) << std::endl; +// { +// "happy": true, +// "pi": 3.141 +// } +``` + +Note the difference between serialization and assignment: + +```cpp +// store a string in a JSON value +json j_string = "this is a string"; + +// retrieve the string value +auto cpp_string = j_string.get(); +// retrieve the string value (alternative when a variable already exists) +std::string cpp_string2; +j_string.get_to(cpp_string2); + +// retrieve the serialized value (explicit JSON serialization) +std::string serialized_string = j_string.dump(); + +// output of original string +std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get() << '\n'; +// output of serialized value +std::cout << j_string << " == " << serialized_string << std::endl; +``` + +[`.dump()`](https://json.nlohmann.me/api/basic_json/dump/) returns the originally stored string value. + +Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://json.nlohmann.me/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers. + +#### To/from streams (e.g. files, string streams) + +You can also use streams to serialize and deserialize: + +```cpp +// deserialize from standard input +json j; +std::cin >> j; + +// serialize to standard output +std::cout << j; + +// the setw manipulator was overloaded to set the indentation for pretty printing +std::cout << std::setw(4) << j << std::endl; +``` + +These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files: + +```cpp +// read a JSON file +std::ifstream i("file.json"); +json j; +i >> j; + +// write prettified JSON to another file +std::ofstream o("pretty.json"); +o << std::setw(4) << j << std::endl; +``` + +Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use. + +#### Read from iterator range + +You can also parse JSON from an iterator range; that is, from any container accessible by iterators whose `value_type` is an integral type of 1, 2 or 4 bytes, which will be interpreted as UTF-8, UTF-16 and UTF-32 respectively. For instance, a `std::vector`, or a `std::list`: + +```cpp +std::vector v = {'t', 'r', 'u', 'e'}; +json j = json::parse(v.begin(), v.end()); +``` + +You may leave the iterators for the range [begin, end): + +```cpp +std::vector v = {'t', 'r', 'u', 'e'}; +json j = json::parse(v); +``` + +#### Custom data source + +Since the parse function accepts arbitrary iterator ranges, you can provide your own data sources by implementing the `LegacyInputIterator` concept. + +```cpp +struct MyContainer { + void advance(); + const char& get_current(); +}; + +struct MyIterator { + using difference_type = std::ptrdiff_t; + using value_type = char; + using pointer = const char*; + using reference = const char&; + using iterator_category = std::input_iterator_tag; + + MyIterator& operator++() { + MyContainer.advance(); + return *this; + } + + bool operator!=(const MyIterator& rhs) const { + return rhs.target != target; + } + + reference operator*() const { + return target.get_current(); + } + + MyContainer* target = nullptr; +}; + +MyIterator begin(MyContainer& tgt) { + return MyIterator{&tgt}; +} + +MyIterator end(const MyContainer&) { + return {}; +} + +void foo() { + MyContainer c; + json j = json::parse(c); +} +``` + +#### SAX interface + +The library uses a SAX-like interface with the following functions: + +```cpp +// called when null is parsed +bool null(); + +// called when a boolean is parsed; value is passed +bool boolean(bool val); + +// called when a signed or unsigned integer number is parsed; value is passed +bool number_integer(number_integer_t val); +bool number_unsigned(number_unsigned_t val); + +// called when a floating-point number is parsed; value and original string is passed +bool number_float(number_float_t val, const string_t& s); + +// called when a string is parsed; value is passed and can be safely moved away +bool string(string_t& val); +// called when a binary value is parsed; value is passed and can be safely moved away +bool binary(binary_t& val); + +// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known) +bool start_object(std::size_t elements); +bool end_object(); +bool start_array(std::size_t elements); +bool end_array(); +// called when an object key is parsed; value is passed and can be safely moved away +bool key(string_t& val); + +// called when a parse error occurs; byte position, the last token, and an exception is passed +bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex); +``` + +The return value of each function determines whether parsing should proceed. + +To implement your own SAX handler, proceed as follows: + +1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax` as base class, but you can also use any class where the functions described above are implemented and public. +2. Create an object of your SAX interface class, e.g. `my_sax`. +3. Call `bool json::sax_parse(input, &my_sax)`; where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface. + +Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp). + +### STL-like access + +We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement. + +```cpp +// create an array using push_back +json j; +j.push_back("foo"); +j.push_back(1); +j.push_back(true); + +// also use emplace_back +j.emplace_back(1.78); + +// iterate the array +for (json::iterator it = j.begin(); it != j.end(); ++it) { + std::cout << *it << '\n'; +} + +// range-based for +for (auto& element : j) { + std::cout << element << '\n'; +} + +// getter/setter +const auto tmp = j[0].get(); +j[1] = 42; +bool foo = j.at(2); + +// comparison +j == R"(["foo", 1, true, 1.78])"_json; // true + +// other stuff +j.size(); // 4 entries +j.empty(); // false +j.type(); // json::value_t::array +j.clear(); // the array is empty again + +// convenience type checkers +j.is_null(); +j.is_boolean(); +j.is_number(); +j.is_object(); +j.is_array(); +j.is_string(); + +// create an object +json o; +o["foo"] = 23; +o["bar"] = false; +o["baz"] = 3.141; + +// also use emplace +o.emplace("weather", "sunny"); + +// special iterator member functions for objects +for (json::iterator it = o.begin(); it != o.end(); ++it) { + std::cout << it.key() << " : " << it.value() << "\n"; +} + +// the same code as range for +for (auto& el : o.items()) { + std::cout << el.key() << " : " << el.value() << "\n"; +} + +// even easier with structured bindings (C++17) +for (auto& [key, value] : o.items()) { + std::cout << key << " : " << value << "\n"; +} + +// find an entry +if (o.contains("foo")) { + // there is an entry with key "foo" +} + +// or via find and an iterator +if (o.find("foo") != o.end()) { + // there is an entry with key "foo" +} + +// or simpler using count() +int foo_present = o.count("foo"); // 1 +int fob_present = o.count("fob"); // 0 + +// delete an entry +o.erase("foo"); +``` + + +### Conversion from STL containers + +Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON values (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container. + +```cpp +std::vector c_vector {1, 2, 3, 4}; +json j_vec(c_vector); +// [1, 2, 3, 4] + +std::deque c_deque {1.2, 2.3, 3.4, 5.6}; +json j_deque(c_deque); +// [1.2, 2.3, 3.4, 5.6] + +std::list c_list {true, true, false, true}; +json j_list(c_list); +// [true, true, false, true] + +std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; +json j_flist(c_flist); +// [12345678909876, 23456789098765, 34567890987654, 45678909876543] + +std::array c_array {{1, 2, 3, 4}}; +json j_array(c_array); +// [1, 2, 3, 4] + +std::set c_set {"one", "two", "three", "four", "one"}; +json j_set(c_set); // only one entry for "one" is used +// ["four", "one", "three", "two"] + +std::unordered_set c_uset {"one", "two", "three", "four", "one"}; +json j_uset(c_uset); // only one entry for "one" is used +// maybe ["two", "three", "four", "one"] + +std::multiset c_mset {"one", "two", "one", "four"}; +json j_mset(c_mset); // both entries for "one" are used +// maybe ["one", "two", "one", "four"] + +std::unordered_multiset c_umset {"one", "two", "one", "four"}; +json j_umset(c_umset); // both entries for "one" are used +// maybe ["one", "two", "one", "four"] +``` + +Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON values (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container. + +```cpp +std::map c_map { {"one", 1}, {"two", 2}, {"three", 3} }; +json j_map(c_map); +// {"one": 1, "three": 3, "two": 2 } + +std::unordered_map c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; +json j_umap(c_umap); +// {"one": 1.2, "two": 2.3, "three": 3.4} + +std::multimap c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; +json j_mmap(c_mmap); // only one entry for key "three" is used +// maybe {"one": true, "two": true, "three": true} + +std::unordered_multimap c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; +json j_ummap(c_ummap); // only one entry for key "three" is used +// maybe {"one": true, "two": true, "three": true} +``` + +### JSON Pointer and JSON Patch + +The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values. On top of this, **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) allows describing differences between two JSON values - effectively allowing patch and diff operations known from Unix. + +```cpp +// a JSON value +json j_original = R"({ + "baz": ["one", "two", "three"], + "foo": "bar" +})"_json; + +// access members with a JSON pointer (RFC 6901) +j_original["/baz/1"_json_pointer]; +// "two" + +// a JSON patch (RFC 6902) +json j_patch = R"([ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} +])"_json; + +// apply the patch +json j_result = j_original.patch(j_patch); +// { +// "baz": "boo", +// "hello": ["world"] +// } + +// calculate a JSON patch from two JSON values +json::diff(j_result, j_original); +// [ +// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] }, +// { "op": "remove","path": "/hello" }, +// { "op": "add", "path": "/foo", "value": "bar" } +// ] +``` + +### JSON Merge Patch + +The library supports **JSON Merge Patch** ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. Instead of using JSON Pointer (see above) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. + +```cpp +// a JSON value +json j_document = R"({ + "a": "b", + "c": { + "d": "e", + "f": "g" + } +})"_json; + +// a patch +json j_patch = R"({ + "a":"z", + "c": { + "f": null + } +})"_json; + +// apply the patch +j_document.merge_patch(j_patch); +// { +// "a": "z", +// "c": { +// "d": "e" +// } +// } +``` + +### Implicit conversions + +Supported types can be implicitly converted to JSON values. + +It is recommended to **NOT USE** implicit conversions **FROM** a JSON value. +You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958). +You can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` before including the `json.hpp` header. When using CMake, you can also achieve this by setting the option `JSON_ImplicitConversions` to `OFF`. + +```cpp +// strings +std::string s1 = "Hello, world!"; +json js = s1; +auto s2 = js.get(); +// NOT RECOMMENDED +std::string s3 = js; +std::string s4; +s4 = js; + +// Booleans +bool b1 = true; +json jb = b1; +auto b2 = jb.get(); +// NOT RECOMMENDED +bool b3 = jb; +bool b4; +b4 = jb; + +// numbers +int i = 42; +json jn = i; +auto f = jn.get(); +// NOT RECOMMENDED +double f2 = jb; +double f3; +f3 = jb; + +// etc. +``` + +Note that `char` types are not automatically converted to JSON strings, but to integer numbers. A conversion to a string must be specified explicitly: + +```cpp +char ch = 'A'; // ASCII value 65 +json j_default = ch; // stores integer number 65 +json j_string = std::string(1, ch); // stores string "A" +``` + +### Arbitrary types conversions + +Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines: + +```cpp +namespace ns { + // a simple struct to model a person + struct person { + std::string name; + std::string address; + int age; + }; +} + +ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// convert to JSON: copy each value into the JSON object +json j; +j["name"] = p.name; +j["address"] = p.address; +j["age"] = p.age; + +// ... + +// convert from JSON: copy each value from the JSON object +ns::person p { + j["name"].get(), + j["address"].get(), + j["age"].get() +}; +``` + +It works, but that's quite a lot of boilerplate... Fortunately, there's a better way: + +```cpp +// create a person +ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// conversion: person -> json +json j = p; + +std::cout << j << std::endl; +// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} + +// conversion: json -> person +auto p2 = j.get(); + +// that's it +assert(p == p2); +``` + +#### Basic usage + +To make this work with one of your types, you only need to provide two functions: + +```cpp +using json = nlohmann::json; + +namespace ns { + void to_json(json& j, const person& p) { + j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}}; + } + + void from_json(const json& j, person& p) { + j.at("name").get_to(p.name); + j.at("address").get_to(p.address); + j.at("age").get_to(p.age); + } +} // namespace ns +``` + +That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. +Likewise, when calling `get()` or `get_to(your_type&)`, the `from_json` method will be called. + +Some important things: + +* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined). +* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise. +* When using `get()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.) +* In function `from_json`, use function [`at()`](https://json.nlohmann.me/api/basic_json/at/) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. +* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. + +#### Simplify your life with macros + +If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate. + +There are two macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object: + +- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the namespace of the class/struct to create code for. +- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the class/struct to create code for. This macro can also access private members. + +In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. + +##### Examples + +The `to_json`/`from_json` functions for the `person` struct above can be created with: + +```cpp +namespace ns { + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age) +} +``` + +Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed: + +```cpp +namespace ns { + class address { + private: + std::string street; + int housenumber; + int postcode; + + public: + NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode) + }; +} +``` + +#### How do I convert third-party types? + +This requires a bit more advanced technique. But first, let's see how this conversion mechanism works: + +The library uses **JSON Serializers** to convert types to json. +The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)). + +It is implemented like this (simplified): + +```cpp +template +struct adl_serializer { + static void to_json(json& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + static void from_json(const json& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`... + +To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example: + +```cpp +// partial specialization (full specialization works too) +namespace nlohmann { + template + struct adl_serializer> { + static void to_json(json& j, const boost::optional& opt) { + if (opt == boost::none) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, boost::optional& opt) { + if (j.is_null()) { + opt = boost::none; + } else { + opt = j.get(); // same as above, but with + // adl_serializer::from_json + } + } + }; +} +``` + +#### How can I use `get()` for non-default constructible/non-copyable types? + +There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload: + +```cpp +struct move_only_type { + move_only_type() = delete; + move_only_type(int ii): i(ii) {} + move_only_type(const move_only_type&) = delete; + move_only_type(move_only_type&&) = default; + + int i; +}; + +namespace nlohmann { + template <> + struct adl_serializer { + // note: the return type is no longer 'void', and the method only takes + // one argument + static move_only_type from_json(const json& j) { + return {j.get()}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert move_only_type to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, move_only_type t) { + j = t.i; + } + }; +} +``` + +#### Can I write my own serializer? (Advanced use) + +Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-udt.cpp) in the test suite, to see a few examples. + +If you write your own serializer, you'll need to do a few things: + +- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`) +- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods +- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL + +Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL. + +```cpp +// You should use void as a second template argument +// if you don't need compile-time checks on T +template::type> +struct less_than_32_serializer { + template + static void to_json(BasicJsonType& j, T value) { + // we want to use ADL, and call the correct to_json overload + using nlohmann::to_json; // this method is called by adl_serializer, + // this is where the magic happens + to_json(j, value); + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing here + using nlohmann::from_json; + from_json(j, value); + } +}; +``` + +Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention: + +```cpp +template +struct bad_serializer +{ + template + static void to_json(BasicJsonType& j, const T& value) { + // this calls BasicJsonType::json_serializer::to_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + j = value; + } + + template + static void to_json(const BasicJsonType& j, T& value) { + // this calls BasicJsonType::json_serializer::from_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + value = j.template get(); // oops! + } +}; +``` + +### Specializing enum conversion + +By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be undefined or a different enum value than was originally intended. + +It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below: + +```cpp +// example enum type declaration +enum TaskState { + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID=-1, +}; + +// map TaskState values to JSON as strings +NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, { + {TS_INVALID, nullptr}, + {TS_STOPPED, "stopped"}, + {TS_RUNNING, "running"}, + {TS_COMPLETED, "completed"}, +}) +``` + +The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code. + +**Usage:** + +```cpp +// enum to JSON as string +json j = TS_STOPPED; +assert(j == "stopped"); + +// json string to enum +json j3 = "running"; +assert(j3.get() == TS_RUNNING); + +// undefined json value to enum (where the first map entry above is the default) +json jPi = 3.14; +assert(jPi.get() == TS_INVALID ); +``` + +Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above, +- `NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization. +- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions. + +Other Important points: +- When using `get()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. +- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON. + +### Binary formats (BSON, CBOR, MessagePack, UBJSON, and BJData) + +Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](https://bsonspec.org) (Binary JSON), [CBOR](https://cbor.io) (Concise Binary Object Representation), [MessagePack](https://msgpack.org), [UBJSON](https://ubjson.org) (Universal Binary JSON Specification) and [BJData](https://neurojson.org/bjdata) (Binary JData) to efficiently encode JSON values to byte vectors and to decode such vectors. + +```cpp +// create a JSON value +json j = R"({"compact": true, "schema": 0})"_json; + +// serialize to BSON +std::vector v_bson = json::to_bson(j); + +// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +// roundtrip +json j_from_bson = json::from_bson(v_bson); + +// serialize to CBOR +std::vector v_cbor = json::to_cbor(j); + +// 0xA2, 0x67, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xF5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00 + +// roundtrip +json j_from_cbor = json::from_cbor(v_cbor); + +// serialize to MessagePack +std::vector v_msgpack = json::to_msgpack(j); + +// 0x82, 0xA7, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xC3, 0xA6, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00 + +// roundtrip +json j_from_msgpack = json::from_msgpack(v_msgpack); + +// serialize to UBJSON +std::vector v_ubjson = json::to_ubjson(j); + +// 0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + +// roundtrip +json j_from_ubjson = json::from_ubjson(v_ubjson); +``` + +The library also supports binary types from BSON, CBOR (byte strings), and MessagePack (bin, ext, fixext). They are stored by default as `std::vector` to be processed outside the library. + +```cpp +// CBOR byte string with payload 0xCAFE +std::vector v = {0x42, 0xCA, 0xFE}; + +// read value +json j = json::from_cbor(v); + +// the JSON value has type binary +j.is_binary(); // true + +// get reference to stored binary value +auto& binary = j.get_binary(); + +// the binary value has no subtype (CBOR has no binary subtypes) +binary.has_subtype(); // false + +// access std::vector member functions +binary.size(); // 2 +binary[0]; // 0xCA +binary[1]; // 0xFE + +// set subtype to 0x10 +binary.set_subtype(0x10); + +// serialize to MessagePack +auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE +``` + + +## Supported compilers + +Though it's 2023 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: + +- GCC 4.8 - 12.0 (and possibly later) +- Clang 3.4 - 15.0 (and possibly later) +- Apple Clang 9.1 - 13.1 (and possibly later) +- Intel C++ Compiler 17.0.2 (and possibly later) +- Nvidia CUDA Compiler 11.0.221 (and possibly later) +- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later) +- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later) +- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later) +- Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later) + +I would be happy to learn about other compilers/versions. + +Please note: + +- GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler. +- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. + + ``` + APP_STL := c++_shared + NDK_TOOLCHAIN_VERSION := clang3.6 + APP_CPPFLAGS += -frtti -fexceptions + ``` + + The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10. + +- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](https://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219). + +- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case. + +The following compilers are currently used in continuous integration at [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), [Cirrus CI](https://cirrus-ci.com/github/nlohmann/json), and [GitHub Actions](https://github.com/nlohmann/json/actions): + +| Compiler | Operating System | CI Provider | +|--------------------------------------------------------------------------------------------------------|--------------------|----------------| +| Apple Clang 11.0.3 (clang-1103.0.32.62); Xcode 11.7 | macOS 11.7.1 | GitHub Actions | +| Apple Clang 12.0.0 (clang-1200.0.32.29); Xcode 12.4 | macOS 11.7.1 | GitHub Actions | +| Apple Clang 12.0.5 (clang-1205.0.22.11); Xcode 12.5.1 | macOS 11.7.1 | GitHub Actions | +| Apple Clang 13.0.0 (clang-1300.0.29.3); Xcode 13.0 | macOS 11.7.1 | GitHub Actions | +| Apple Clang 13.0.0 (clang-1300.0.29.3); Xcode 13.1 | macOS 12.6.1 | GitHub Actions | +| Apple Clang 13.0.0 (clang-1300.0.29.30); Xcode 13.2.1 | macOS 12.6.1 | GitHub Actions | +| Apple Clang 13.1.6 (clang-1316.0.21.2.3); Xcode 13.3.1 | macOS 12.6.1 | GitHub Actions | +| Apple Clang 13.1.6 (clang-1316.0.21.2.5); Xcode 13.4.1 | macOS 12.6.1 | GitHub Actions | +| Apple Clang 14.0.0 (clang-1400.0.29.102); Xcode 14.0 | macOS 12.6.1 | GitHub Actions | +| Apple Clang 14.0.0 (clang-1400.0.29.102); Xcode 14.0.1 | macOS 12.6.1 | GitHub Actions | +| Apple Clang 14.0.0 (clang-1400.0.29.202); Xcode 14.1 | macOS 12.6.1 | GitHub Actions | +| Clang 3.5.2 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 3.6.2 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 3.7.1 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 3.8.1 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 3.9.1 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 4.0.1 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 5.0.2 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 6.0.1 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 7.0.1 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 8.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 9.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 10.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 10.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 11.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 11.0.0 with MSVC-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 11.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 12.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 12.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 13.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 13.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 14.0.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 14.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 15.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | +| Clang 15.0.4 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Clang 16.0.0 (16.0.0-++20221031071727+500876226c60-1~exp1~20221031071831.439) | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu2) | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 4.9.4 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 5.5.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 6.5.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 7.5.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project) | Windows-10.0.17763 | GitHub Actions | +| GCC 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) | Windows-10.0.17763 | GitHub Actions | +| GCC 8.5.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 9.5.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 10.4.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 11.1.0 | Ubuntu (aarch64) | Cirrus CI | +| GCC 11.3.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 12.2.0 | Ubuntu 20.04.3 LTS | GitHub Actions | +| GCC 13.0.0 20220605 (experimental) | Ubuntu 20.04.3 LTS | GitHub Actions | +| Intel C++ Compiler 2021.5.0.20211109 | Ubuntu 20.04.3 LTS | GitHub Actions | +| NVCC 11.0.221 | Ubuntu 20.04.3 LTS | GitHub Actions | +| Visual Studio 14 2015 MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1) | Windows-6.3.9600 | AppVeyor | +| Visual Studio 15 2017 MSVC 19.16.27035.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor | +| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework) | Windows-10.0.17763 | GitHub Actions | +| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework) | Windows-10.0.17763 | AppVeyor | +| Visual Studio 17 2022 MSVC 19.30.30709.0 (Build Engine version 17.0.31804.368 for .NET Framework) | Windows-10.0.20348 | GitHub Actions | + + +## Integration + +[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add + +```cpp +#include + +// for convenience +using json = nlohmann::json; +``` + +to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang). + +You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`. + +### CMake + +You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags. + +#### External + +To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration: + +```cmake +# CMakeLists.txt +find_package(nlohmann_json 3.2.0 REQUIRED) +... +add_library(foo ...) +... +target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) +``` + +The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree. + +#### Embedded + +To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file: + +```cmake +# Typically you don't care so much for a third party library's tests to be +# run from your own project's code. +set(JSON_BuildTests OFF CACHE INTERNAL "") + +# If you only include this third party in PRIVATE source files, you do not +# need to install it when your main project gets installed. +# set(JSON_Install OFF CACHE INTERNAL "") + +# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it +# unintended consequences that will break the build. It's generally +# discouraged (although not necessarily well documented as such) to use +# include(...) for pulling in other CMake projects anyways. +add_subdirectory(nlohmann_json) +... +add_library(foo ...) +... +target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) +``` + +##### Embedded (FetchContent) + +Since CMake v3.11, +[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can +be used to automatically download a release as a dependency at configure time. + +Example: +```cmake +include(FetchContent) + +FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz) +FetchContent_MakeAvailable(json) + +target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) +``` + +**Note**: It is recommended to use the URL approach described above which is supported as of version 3.10.0. See + for more information. + +#### Supporting Both + +To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following: + +``` cmake +# Top level CMakeLists.txt +project(FOO) +... +option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF) +... +add_subdirectory(thirdparty) +... +add_library(foo ...) +... +# Note that the namespaced target will always be available regardless of the +# import method +target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) +``` +```cmake +# thirdparty/CMakeLists.txt +... +if(FOO_USE_EXTERNAL_JSON) + find_package(nlohmann_json 3.2.0 REQUIRED) +else() + set(JSON_BuildTests OFF CACHE INTERNAL "") + add_subdirectory(nlohmann_json) +endif() +... +``` + +`thirdparty/nlohmann_json` is then a complete copy of this source tree. + +### Package Managers + +:beer: If you are using OS X and [Homebrew](https://brew.sh), just type `brew install nlohmann-json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann-json --HEAD`. See [nlohmann-json](https://formulae.brew.sh/formula/nlohmann-json) for more information. + +If you are using the [Meson Build System](https://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging. + +The provided `meson.build` can also be used as an alternative to CMake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly. + +If you are using [Bazel](https://bazel.build/) you can simply reference this repository using `http_archive` or `git_repository` and depend on `@nlohmann_json//:json`. + +If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add [`nlohmann_json/x.y.z`](https://conan.io/center/nlohmann_json) to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages. + +If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging. + +If you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging. + +If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example). + +If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can install the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) with `vcpkg install nlohmann-json` and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging. + +If you are using [cget](https://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`). + +If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open). + +If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please file issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues). + +If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues). + +If you are using [MSYS2](https://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages. + +If you are using [MacPorts](https://ports.macports.org), execute `sudo port install nlohmann-json` to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package. + +If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository https://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml). +Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages. + +If you are using [`wsjcpp`](https://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch. + +If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake: + +```cmake +CPMAddPackage( + NAME nlohmann_json + GITHUB_REPOSITORY nlohmann/json + VERSION 3.9.1) +``` + +### Pkg-config + +If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed: + +```sh +pkg-config nlohmann_json --cflags +``` + +Users of the Meson build system will also be able to use a system-wide library, which will be found by `pkg-config`: + +```meson +json = dependency('nlohmann_json', required: true) +``` + + +## License + + + +The class is licensed under the [MIT License](https://opensource.org/licenses/MIT): + +Copyright © 2013-2022 [Niels Lohmann](https://nlohmann.me) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +* * * + +The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2008-2009 [Björn Hoehrmann](https://bjoern.hoehrmann.de/) + +The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/) + +The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). + +The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0). + +## Contact + +If you have questions regarding the library, I would like to invite you to [open an issue at GitHub](https://github.com/nlohmann/json/issues/new/choose). Please describe your request, problem, or question as detailed as possible, and also mention the version of the library you are using as well as the version of your compiler and operating system. Opening an issue at GitHub allows other users and contributors to this library to collaborate. For instance, I have little experience with MSVC, and most issues in this regard have been solved by a growing community. If you have a look at the [closed issues](https://github.com/nlohmann/json/issues?q=is%3Aissue+is%3Aclosed), you will see that we react quite timely in most cases. + +Only if your request would contain confidential information, please [send me an email](mailto:mail@nlohmann.me). For encrypted messages, please use [this key](https://keybase.io/nlohmann/pgp_keys.asc). + +## Security + +[Commits by Niels Lohmann](https://github.com/nlohmann/json/commits) and [releases](https://github.com/nlohmann/json/releases) are signed with this [PGP Key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69). + +## Thanks + +I deeply appreciate the help of the following people. + + + +1. [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization. +2. [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes. +3. [kirkshoop](https://github.com/kirkshoop) made the iterators of the class composable to other libraries. +4. [wancw](https://github.com/wanwc) fixed a bug that hindered the class to compile with Clang. +5. Tomas Åblad found a bug in the iterator implementation. +6. [Joshua C. Randall](https://github.com/jrandall) fixed a bug in the floating-point serialization. +7. [Aaron Burghardt](https://github.com/aburgh) implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing. +8. [Daniel Kopeček](https://github.com/dkopecek) fixed a bug in the compilation with GCC 5.0. +9. [Florian Weber](https://github.com/Florianjw) fixed a bug in and improved the performance of the comparison operators. +10. [Eric Cornelius](https://github.com/EricMCornelius) pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping. +11. [易思龙](https://github.com/likebeta) implemented a conversion from anonymous enums. +12. [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual studio. +13. [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types. +14. [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling. +15. [dariomt](https://github.com/dariomt) fixed some typos in the examples. +16. [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation. +17. [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue. +18. [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation. +19. [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference. +20. [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values. +21. [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK. +22. [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio. +23. [406345](https://github.com/406345) fixed two small warnings. +24. [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. +25. [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. +26. [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers. +27. [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file. +28. [msm-](https://github.com/msm-) added support for American Fuzzy Lop. +29. [Annihil](https://github.com/Annihil) fixed an example in the README file. +30. [Themercee](https://github.com/Themercee) noted a wrong URL in the README file. +31. [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`. +32. [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212). +33. [zewt](https://github.com/zewt) added useful notes to the README file about Android. +34. [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake. +35. [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files. +36. [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal). +37. [Mário Feroldi](https://github.com/thelostt) fixed a small typo. +38. [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release. +39. [Damien](https://github.com/dtoma) fixed one of the last conversion warnings. +40. [Thomas Braun](https://github.com/t-b) fixed a warning in a test case and adjusted MSVC calls in the CI. +41. [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks. +42. [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation. +43. [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`. +44. [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion. +45. [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix. +46. [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file. +47. [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function. +48. [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing. +49. [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan. +50. [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning. +51. [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check. +52. [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one. +53. [Daniel599](https://github.com/Daniel599) helped to get Travis execute the tests with Clang's sanitizers. +54. [Jonathan Lee](https://github.com/vjon) fixed an example in the README file. +55. [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types. +56. [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio. +57. [Jared Grubb](https://github.com/jaredgrubb) supported the implementation of user-defined types. +58. [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example. +59. [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite. +60. [ukhegg](https://github.com/ukhegg) found proposed an improvement for the examples section. +61. [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README. +62. [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s. +63. [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation. +64. [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings. +65. [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible. +66. [ftillier](https://github.com/ftillier) fixed a compiler warning. +67. [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped. +68. [Fytch](https://github.com/Fytch) found a bug in the documentation. +69. [Jay Sistar](https://github.com/Type1J) implemented a Meson build description. +70. [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation. +71. [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager. +72. [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`. +73. [Mike Tzou](https://github.com/Chocobo1) fixed some typos. +74. [amrcode](https://github.com/amrcode) noted a misleading documentation about comparison of floats. +75. [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `` with ``. +76. [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library. +77. [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists. +78. [Greg Hurrell](https://github.com/wincent) fixed a typo. +79. [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo. +80. [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler. +81. [Markus Werle](https://github.com/daixtrose) fixed a typo. +82. [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check. +83. [Alex](https://github.com/leha-bot) noted an error in a code sample. +84. [Tom de Geus](https://github.com/tdegeus) reported some warnings with ICC and helped to fix them. +85. [Perry Kundert](https://github.com/pjkundert) simplified reading from input streams. +86. [Sonu Lohani](https://github.com/sonulohani) fixed a small compilation error. +87. [Jamie Seward](https://github.com/jseward) fixed all MSVC warnings. +88. [Nate Vargas](https://github.com/eld00d) added a Doxygen tag file. +89. [pvleuven](https://github.com/pvleuven) helped to fix a warning in ICC. +90. [Pavel](https://github.com/crea7or) helped to fix some warnings in MSVC. +91. [Jamie Seward](https://github.com/jseward) avoided unnecessary string copies in `find()` and `count()`. +92. [Mitja](https://github.com/Itja) fixed some typos. +93. [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links. +94. [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view. +95. [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings. +96. [Eren Okka](https://github.com/erengy) fixed some MSVC warnings. +97. [abolz](https://github.com/abolz) integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed. +98. [Vadim Evard](https://github.com/Pipeliner) fixed a Markdown issue in the README. +99. [zerodefect](https://github.com/zerodefect) fixed a compiler warning. +100. [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior. +101. [mark-99](https://github.com/mark-99) helped fixing an ICC error. +102. [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file. +103. [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings. +104. [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager. +105. [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise. +106. [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback. +107. [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type. +108. [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake. +109. [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io). +110. [Carlos O'Ryan](https://github.com/coryan) fixed a typo. +111. [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section. +112. [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration. +113. [Jan Schöppach](https://github.com/dns13) fixed a typo. +114. [martin-mfg](https://github.com/martin-mfg) fixed a typo. +115. [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`. +116. [agrianius](https://github.com/agrianius) added code to use alternative string implementations. +117. [Daniel599](https://github.com/Daniel599) allowed to use more algorithms with the `items()` function. +118. [Julius Rakow](https://github.com/jrakow) fixed the Meson include directory and fixed the links to [cppreference.com](cppreference.com). +119. [Sonu Lohani](https://github.com/sonulohani) fixed the compilation with MSVC 2015 in debug mode. +120. [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases. +121. [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library. +122. [thyu](https://github.com/thyu) fixed a compiler warning. +123. [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2. +124. [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library. +125. [Hyeon Kim](https://github.com/simnalamburt) fixed an issue with a double macro definition. +126. [Ben Berman](https://github.com/rivertam) made some error messages more understandable. +127. [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler. +128. [mandreyel](https://github.com/mandreyel) fixed a compilation problem. +129. [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file. +130. [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8. +131. [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory. +132. [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning. +133. [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define an enum/JSON mapping. +134. [efp](https://github.com/efp) added line and column information to parse errors. +135. [julian-becker](https://github.com/julian-becker) added BSON support. +136. [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings. +137. [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version). +138. [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`. +139. [kjpus](https://github.com/kjpus) fixed a link in the documentation. +140. [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation. +141. [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning. +142. [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC. +143. [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream. +144. [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson. +145. [Michael Behrns-Miller](https://github.com/moodboom) found an issue with a missing namespace. +146. [Nasztanovics Ferenc](https://github.com/naszta) fixed a compilation issue with libc 2.12. +147. [Andreas Schwab](https://github.com/andreas-schwab) fixed the endian conversion. +148. [Mark-Dunning](https://github.com/Mark-Dunning) fixed a warning in MSVC. +149. [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) added `operator/` for JSON Pointers. +150. [John-Mark](https://github.com/johnmarkwayve) noted a missing header. +151. [Vitaly Zaitsev](https://github.com/xvitaly) fixed compilation with GCC 9.0. +152. [Laurent Stacul](https://github.com/stac47) fixed compilation with GCC 9.0. +153. [Ivor Wanders](https://github.com/iwanders) helped to reduce the CMake requirement to version 3.1. +154. [njlr](https://github.com/njlr) updated the Buckaroo instructions. +155. [Lion](https://github.com/lieff) fixed a compilation issue with GCC 7 on CentOS. +156. [Isaac Nickaein](https://github.com/nickaein) improved the integer serialization performance and implemented the `contains()` function. +157. [past-due](https://github.com/past-due) suppressed an unfixable warning. +158. [Elvis Oric](https://github.com/elvisoric) improved Meson support. +159. [Matěj Plch](https://github.com/Afforix) fixed an example in the README. +160. [Mark Beckwith](https://github.com/wythe) fixed a typo. +161. [scinart](https://github.com/scinart) fixed bug in the serializer. +162. [Patrick Boettcher](https://github.com/pboettch) implemented `push_back()` and `pop_back()` for JSON Pointers. +163. [Bruno Oliveira](https://github.com/nicoddemus) added support for Conda. +164. [Michele Caini](https://github.com/skypjack) fixed links in the README. +165. [Hani](https://github.com/hnkb) documented how to install the library with NuGet. +166. [Mark Beckwith](https://github.com/wythe) fixed a typo. +167. [yann-morin-1998](https://github.com/yann-morin-1998) helped to reduce the CMake requirement to version 3.1. +168. [Konstantin Podsvirov](https://github.com/podsvirov) maintains a package for the MSYS2 software distro. +169. [remyabel](https://github.com/remyabel) added GNUInstallDirs to the CMake files. +170. [Taylor Howard](https://github.com/taylorhoward92) fixed a unit test. +171. [Gabe Ron](https://github.com/Macr0Nerd) implemented the `to_string` method. +172. [Watal M. Iwasaki](https://github.com/heavywatal) fixed a Clang warning. +173. [Viktor Kirilov](https://github.com/onqtam) switched the unit tests from [Catch](https://github.com/philsquared/Catch) to [doctest](https://github.com/onqtam/doctest) +174. [Juncheng E](https://github.com/ejcjason) fixed a typo. +175. [tete17](https://github.com/tete17) fixed a bug in the `contains` function. +176. [Xav83](https://github.com/Xav83) fixed some cppcheck warnings. +177. [0xflotus](https://github.com/0xflotus) fixed some typos. +178. [Christian Deneke](https://github.com/chris0x44) added a const version of `json_pointer::back`. +179. [Julien Hamaide](https://github.com/crazyjul) made the `items()` function work with custom string types. +180. [Evan Nemerson](https://github.com/nemequ) updated fixed a bug in Hedley and updated this library accordingly. +181. [Florian Pigorsch](https://github.com/flopp) fixed a lot of typos. +182. [Camille Bégué](https://github.com/cbegue) fixed an issue in the conversion from `std::pair` and `std::tuple` to `json`. +183. [Anthony VH](https://github.com/AnthonyVH) fixed a compile error in an enum deserialization. +184. [Yuriy Vountesmery](https://github.com/ua-code-dragon) noted a subtle bug in a preprocessor check. +185. [Chen](https://github.com/dota17) fixed numerous issues in the library. +186. [Antony Kellermann](https://github.com/aokellermann) added a CI step for GCC 10.1. +187. [Alex](https://github.com/gistrec) fixed an MSVC warning. +188. [Rainer](https://github.com/rvjr) proposed an improvement in the floating-point serialization in CBOR. +189. [Francois Chabot](https://github.com/FrancoisChabot) made performance improvements in the input adapters. +190. [Arthur Sonzogni](https://github.com/ArthurSonzogni) documented how the library can be included via `FetchContent`. +191. [Rimas Misevičius](https://github.com/rmisev) fixed an error message. +192. [Alexander Myasnikov](https://github.com/alexandermyasnikov) fixed some examples and a link in the README. +193. [Hubert Chathi](https://github.com/uhoreg) made CMake's version config file architecture-independent. +194. [OmnipotentEntity](https://github.com/OmnipotentEntity) implemented the binary values for CBOR, MessagePack, BSON, and UBJSON. +195. [ArtemSarmini](https://github.com/ArtemSarmini) fixed a compilation issue with GCC 10 and fixed a leak. +196. [Evgenii Sopov](https://github.com/sea-kg) integrated the library to the wsjcpp package manager. +197. [Sergey Linev](https://github.com/linev) fixed a compiler warning. +198. [Miguel Magalhães](https://github.com/magamig) fixed the year in the copyright. +199. [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) fixed a compilation issue with MSVC. +200. [Alexander “weej” Jones](https://github.com/alex-weej) fixed an example in the README. +201. [Antoine Cœur](https://github.com/Coeur) fixed some typos in the documentation. +202. [jothepro](https://github.com/jothepro) updated links to the Hunter package. +203. [Dave Lee](https://github.com/kastiglione) fixed link in the README. +204. [Joël Lamotte](https://github.com/Klaim) added instruction for using Build2's package manager. +205. [Paul Jurczak](https://github.com/pauljurczak) fixed an example in the README. +206. [Sonu Lohani](https://github.com/sonulohani) fixed a warning. +207. [Carlos Gomes Martinho](https://github.com/gocarlos) updated the Conan package source. +208. [Konstantin Podsvirov](https://github.com/podsvirov) fixed the MSYS2 package documentation. +209. [Tridacnid](https://github.com/Tridacnid) improved the CMake tests. +210. [Michael](https://github.com/MBalszun) fixed MSVC warnings. +211. [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation. +212. [XyFreak](https://github.com/XyFreak) fixed a compiler warning. +213. [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README. +214. [Tanuj Garg](https://github.com/tanuj208) improved the fuzzer coverage for UBSAN input. +215. [AODQ](https://github.com/AODQ) fixed a compiler warning. +216. [jwittbrodt](https://github.com/jwittbrodt) made `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` inline. +217. [pfeatherstone](https://github.com/pfeatherstone) improved the upper bound of arguments of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros. +218. [Jan Procházka](https://github.com/jprochazk) fixed a bug in the CBOR parser for binary and string values. +219. [T0b1-iOS](https://github.com/T0b1-iOS) fixed a bug in the new hash implementation. +220. [Matthew Bauer](https://github.com/matthewbauer) adjusted the CBOR writer to create tags for binary subtypes. +221. [gatopeich](https://github.com/gatopeich) implemented an ordered map container for `nlohmann::ordered_json`. +222. [Érico Nogueira Rolim](https://github.com/ericonr) added support for pkg-config. +223. [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros. +224. [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support. +225. [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`. +226. [Hannes Domani](https://github.com/ssbssa) provided a GDB pretty printer. +227. Lars Wirzenius reviewed the README file. +228. [Jun Jie](https://github.com/ongjunjie) fixed a compiler path in the CMake scripts. +229. [Ronak Buch](https://github.com/rbuch) fixed typos in the documentation. +230. [Alexander Karzhenkov](https://github.com/karzhenkov) fixed a move constructor and the Travis builds. +231. [Leonardo Lima](https://github.com/leozz37) added CPM.Cmake support. +232. [Joseph Blackman](https://github.com/jbzdarkid) fixed a warning. +233. [Yaroslav](https://github.com/YarikTH) updated doctest and implemented unit tests. +234. [Martin Stump](https://github.com/globberwops) fixed a bug in the CMake files. +235. [Jaakko Moisio](https://github.com/jasujm) fixed a bug in the input adapters. +236. [bl-ue](https://github.com/bl-ue) fixed some Markdown issues in the README file. +237. [William A. Wieselquist](https://github.com/wawiesel) fixed an example from the README. +238. [abbaswasim](https://github.com/abbaswasim) fixed an example from the README. +239. [Remy Jette](https://github.com/remyjette) fixed a warning. +240. [Fraser](https://github.com/frasermarlow) fixed the documentation. +241. [Ben Beasley](https://github.com/musicinmybrain) updated doctest. +242. [Doron Behar](https://github.com/doronbehar) fixed pkg-config.pc. +243. [raduteo](https://github.com/raduteo) fixed a warning. +244. [David Pfahler](https://github.com/theShmoo) added the possibility to compile the library without I/O support. +245. [Morten Fyhn Amundsen](https://github.com/mortenfyhn) fixed a typo. +246. [jpl-mac](https://github.com/jpl-mac) allowed to treat the library as a system header in CMake. +247. [Jason Dsouza](https://github.com/jasmcaus) fixed the indentation of the CMake file. +248. [offa](https://github.com/offa) added a link to Conan Center to the documentation. +249. [TotalCaesar659](https://github.com/TotalCaesar659) updated the links in the documentation to use HTTPS. +250. [Rafail Giavrimis](https://github.com/grafail) fixed the Google Benchmark default branch. +251. [Louis Dionne](https://github.com/ldionne) fixed a conversion operator. +252. [justanotheranonymoususer](https://github.com/justanotheranonymoususer) made the examples in the README more consistent. +253. [Finkman](https://github.com/Finkman) suppressed some `-Wfloat-equal` warnings. +254. [Ferry Huberts](https://github.com/fhuberts) fixed `-Wswitch-enum` warnings. +255. [Arseniy Terekhin](https://github.com/senyai) made the GDB pretty-printer robust against unset variable names. +256. [Amir Masoud Abdol](https://github.com/amirmasoudabdol) updated the Homebrew command as nlohmann/json is now in homebrew-core. +257. [Hallot](https://github.com/Hallot) fixed some `-Wextra-semi-stmt warnings`. +258. [Giovanni Cerretani](https://github.com/gcerretani) fixed `-Wunused` warnings on `JSON_DIAGNOSTICS`. +259. [Bogdan Popescu](https://github.com/Kapeli) hosts the [docset](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B) for offline documentation viewers. +260. [Carl Smedstad](https://github.com/carlsmedstad) fixed an assertion error when using `JSON_DIAGNOSTICS`. +261. [miikka75](https://github.com/miikka75) provided an important fix to compile C++17 code with Clang 9. +262. [Maarten Becker](https://github.com/kernie) fixed a warning for shadowed variables. +263. [Cristi Vîjdea](https://github.com/axnsan12) fixed typos in the `operator[]` documentation. +264. [Alex Beregszaszi](https://github.com/axic) fixed spelling mistakes in comments. +265. [Dirk Stolle](https://github.com/striezel) fixed typos in documentation. +266. [Daniel Albuschat](https://github.com/daniel-kun) corrected the parameter name in the `parse` documentation. +267. [Prince Mendiratta](https://github.com/Prince-Mendiratta) fixed a link to the FAQ. +268. [Florian Albrechtskirchinger](https://github.com/falbrechtskirchinger) implemented `std::string_view` support for object keys and made dozens of other improvements. +269. [Qianqian Fang](https://github.com/fangq) implemented the Binary JData (BJData) format. +270. [pketelsen](https://github.com/pketelsen) added macros `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` and `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. +271. [DarkZeros](https://github.com/DarkZeros) adjusted to code to not clash with Arduino defines. +272. [flagarde](https://github.com/flagarde) fixed the output of `meta()` for MSVC. +273. [Giovanni Cerretani](https://github.com/gcerretani) fixed a check for `std::filesystem`. +274. [Dimitris Apostolou](https://github.com/rex4539) fixed a typo. +275. [Ferry Huberts](https://github.com/fhuberts) fixed a typo. +276. [Michael Nosthoff](https://github.com/heinemml) fixed a typo. +277. [JungHoon Lee](https://github.com/jhnlee) fixed a typo. +278. [Faruk D.](https://github.com/fdiblen) fixed the CITATION.CFF file. +279. [Andrea Cocito](https://github.com/puffetto) added a clarification on macro usage to the documentation. +280. [Krzysiek Karbowiak](https://github.com/kkarbowiak) refactored the tests to use `CHECK_THROWS_WITH_AS`. +281. [Chaoqi Zhang](https://github.com/prncoprs) fixed a typo. +282. [ivanovmp](https://github.com/ivanovmp) fixed a whitespace error. +283. [KsaNL](https://github.com/KsaNL) fixed a build error when including ``. +284. [Andrea Pappacoda](https://github.com/Tachi107) moved `.pc` and `.cmake` files to `share` directory. +285. [Wolf Vollprecht](https://github.com/wolfv) added the `patch_inplace` function. +286. [Jake Zimmerman](https://github.com/jez) highlighted common usage patterns in the README file. +287. [NN](https://github.com/NN---) added the Visual Studio output directory to `.gitignore`. +288. [Romain Reignier](https://github.com/romainreignier) improved the performance the vector output adapter. +289. [Mike](https://github.com/Mike-Leo-Smith) fixed the `std::iterator_traits`. +290. [Richard Hozák](https://github.com/zxey) added macro `JSON_NO_ENUM` to disable default enum conversions. +291. [vakokako](https://github.com/vakokako) fixed tests when compiling with C++20. +292. [Alexander “weej” Jones](https://github.com/alexweej) fixed an example in the README. +293. [Eli Schwartz](https://github.com/eli-schwartz) added more files to the `include.zip` archive. +294. [Kevin Lu](https://github.com/kevinlul) fixed a compilation issue when typedefs with certain names were present. +295. [Trevor Hickey](https://github.com/luxe) improved the description of an example. +296. [Jef LeCompte](https://github.com/jef) updated the year in the README file. +297. [Alexandre Hamez](https://github.com/ahamez) fixed a warning. +298. [Maninderpal Badhan](https://github.com/mbadhan) fixed a typo. +299. [kevin--](https://github.com/kevin--) added a note to an example in the README file. +300. [I](https://github.com/wx257osn2) fixed a typo. +301. [Gregorio Litenstein](https://github.com/Lord-Kamina) fixed the Clang detection. +302. [Andreas Smas](https://github.com/andoma) added a Doozer badge. +303. [WanCW](https://github.com/wancw) fixed the string conversion with Clang. +304. [zhaohuaxishi](https://github.com/zhaohuaxishi) fixed a Doxygen error. +305. [emvivre](https://github.com/emvivre) removed an invalid parameter from CMake. +306. [Tobias Hermann](https://github.com/Dobiasd) fixed a link in the README file. +307. [Michael](https://github.com/traits) fixed a warning. +308. [Ryan Mulder](https://github.com/ryanjmulder) added `ensure_ascii` to the `dump` function. +309. [Muri Nicanor](https://github.com/murinicanor) fixed the `sed` discovery in the Makefile. +310. [David Avedissian](https://github.com/dgavedissian) implemented SFINAE-friendly `iterator_traits`. +311. [AQNOUCH Mohammed](https://github.com/aqnouch) fixed a typo in the README. +312. [Gareth Sylvester-Bradley](https://github.com/garethsb) added `operator/=` and `operator/` to construct JSON pointers. +313. [Michael Macnair](https://github.com/mykter) added support for afl-fuzz testing. +314. [Berkus Decker](https://github.com/berkus) fixed a typo in the README. +315. [Illia Polishchuk](https://github.com/effolkronium) improved the CMake testing. +316. [Ikko Ashimine](https://github.com/eltociear) fixed a typo. + +Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. + + +## Used third-party tools + +The library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot! + +- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file +- [**American fuzzy lop**](https://lcamtuf.coredump.cx/afl/) for fuzz testing +- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows +- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code indentation +- [**Clang**](https://clang.llvm.org) for compilation with code sanitizers +- [**CMake**](https://cmake.org) for build automation +- [**Codacy**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json) +- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json) +- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json) +- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis +- [**doctest**](https://github.com/onqtam/doctest) for the unit tests +- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages +- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md) +- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks +- [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros +- [**lcov**](http://ltp.sourceforge.net/coverage/lcov.php) to process coverage information and create an HTML view +- [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz +- [**Material for MkDocs**](https://squidfunk.github.io/mkdocs-material/) for the style of the documentation site +- [**MkDocs**](https://www.mkdocs.org) for the documentation site +- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json)) +- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments. +- [**Valgrind**](https://valgrind.org) to check for correct memory management + + +## Projects using JSON for Modern C++ + +The library is currently used in Apple macOS Sierra-Monterey and iOS 10-15. I am not sure what they are using the library for, but I am happy that it runs on so many devices. + + +## Notes + +### Character encoding + +The library supports **Unicode input** as follows: + +- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1). +- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers. +- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors. +- [Unicode noncharacters](https://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library. +- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors. +- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs. +- When you store strings with different encodings in the library, calling [`dump()`](https://json.nlohmann.me/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers. +- To store wide strings (e.g., `std::wstring`), you need to convert them to a UTF-8 encoded `std::string` before, see [an example](https://json.nlohmann.me/home/faq/#wide-string-handling). + +### Comments in JSON + +This library does not support comments by default. It does so for three reasons: + +1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript. +2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012: + + > I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't. + + > Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser. + +3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this. + +However, you can pass set parameter `ignore_comments` to true in the `parse` function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace. + +### Order of object keys + +By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". + +If you do want to preserve the insertion order, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179). Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). + +### Memory Release + +We checked with Valgrind and the Address Sanitizer (ASAN) that there are no memory leaks. + +If you find that a parsing program with this library does not release memory, please consider the following case, and it may be unrelated to this library. + +**Your program is compiled with glibc.** There is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. If in your program you make lots of small allocations and those small allocations are not a contiguous block and are presumably below the threshold, then they will not get returned to the OS. +Here is a related issue [#1924](https://github.com/nlohmann/json/issues/1924). + +### Further notes + +- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://json.nlohmann.me/api/basic_json/at/). Furthermore, you can define `JSON_ASSERT(x)` to replace calls to `assert(x)`. +- As the exact number type is not defined in the [JSON specification](https://tools.ietf.org/html/rfc8259.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions. +- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag. +- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +## Execute unit tests + +To compile and run the tests, you need to execute + +```sh +$ mkdir build +$ cd build +$ cmake .. -DJSON_BuildTests=On +$ cmake --build . +$ ctest --output-on-failure +``` + +Note that during the `ctest` stage, several JSON test files are downloaded from an [external repository](https://github.com/nlohmann/json_test_data). If policies forbid downloading artifacts during testing, you can download the files yourself and pass the directory with the test files via `-DJSON_TestDataDirectory=path` to CMake. Then, no Internet connectivity is required. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information. + +If the test suite is not found, several test suites will fail like this: + +``` +=============================================================================== +json/tests/src/make_test_data_available.hpp:21: +TEST CASE: check test suite is downloaded + +json/tests/src/make_test_data_available.hpp:23: FATAL ERROR: REQUIRE( utils::check_testsuite_downloaded() ) is NOT correct! + values: REQUIRE( false ) + logged: Test data not found in 'json/cmake-build-debug/json_test_data'. + Please execute target 'download_test_data' before running this test suite. + See for more information. + +=============================================================================== +``` + +In case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure` will fail. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information. + +Some tests change the installed files and hence make the whole process not reproducible. Please execute `ctest -LE not_reproducible` to skip these tests. See [issue #2324](https://github.com/nlohmann/json/issues/2324) for more information. + +Note you need to call `cmake -LE "not_reproducible|git_required"` to exclude both labels. See [issue #2596](https://github.com/nlohmann/json/issues/2596) for more information. + +As Intel compilers use unsafe floating point optimization by default, the unit tests may fail. Use flag [`/fp:precise`](https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/floating-point-options/fp-model-fp.html) then. diff --git a/json-develop/WORKSPACE.bazel b/json-develop/WORKSPACE.bazel new file mode 100644 index 0000000..2b2ae9d --- /dev/null +++ b/json-develop/WORKSPACE.bazel @@ -0,0 +1 @@ +workspace(name = "nlohmann_json") diff --git a/json-develop/cmake/ci.cmake b/json-develop/cmake/ci.cmake new file mode 100644 index 0000000..d07ab92 --- /dev/null +++ b/json-develop/cmake/ci.cmake @@ -0,0 +1,981 @@ +# number of parallel jobs for CTest +set(N 10) + +############################################################################### +# Needed tools. +############################################################################### + +include(FindPython3) +find_package(Python3 COMPONENTS Interpreter) + +find_program(ASTYLE_TOOL NAMES astyle) +execute_process(COMMAND ${ASTYLE_TOOL} --version OUTPUT_VARIABLE ASTYLE_TOOL_VERSION ERROR_VARIABLE ASTYLE_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" ASTYLE_TOOL_VERSION "${ASTYLE_TOOL_VERSION}") +message(STATUS "🔖 Artistic Style ${ASTYLE_TOOL_VERSION} (${ASTYLE_TOOL})") + +find_program(CLANG_TOOL NAMES clang++-HEAD clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++) +execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}") +message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})") + +find_program(CLANG_TIDY_TOOL NAMES clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy) +execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}") +message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})") + +message(STATUS "🔖 CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})") + +find_program(CPPCHECK_TOOL NAMES cppcheck) +execute_process(COMMAND ${CPPCHECK_TOOL} --version OUTPUT_VARIABLE CPPCHECK_TOOL_VERSION ERROR_VARIABLE CPPCHECK_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CPPCHECK_TOOL_VERSION "${CPPCHECK_TOOL_VERSION}") +message(STATUS "🔖 Cppcheck ${CPPCHECK_TOOL_VERSION} (${CPPCHECK_TOOL})") + +find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++-12 g++-11 g++-10) +execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}") +message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})") + +find_program(GCOV_TOOL NAMES gcov-HEAD gcov-11 gcov-10 gcov) +execute_process(COMMAND ${GCOV_TOOL} --version OUTPUT_VARIABLE GCOV_TOOL_VERSION ERROR_VARIABLE GCOV_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCOV_TOOL_VERSION "${GCOV_TOOL_VERSION}") +message(STATUS "🔖 GCOV ${GCOV_TOOL_VERSION} (${GCOV_TOOL})") + +find_program(GIT_TOOL NAMES git) +execute_process(COMMAND ${GIT_TOOL} --version OUTPUT_VARIABLE GIT_TOOL_VERSION ERROR_VARIABLE GIT_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GIT_TOOL_VERSION "${GIT_TOOL_VERSION}") +message(STATUS "🔖 Git ${GIT_TOOL_VERSION} (${GIT_TOOL})") + +find_program(IWYU_TOOL NAMES include-what-you-use iwyu) +execute_process(COMMAND ${IWYU_TOOL} --version OUTPUT_VARIABLE IWYU_TOOL_VERSION ERROR_VARIABLE IWYU_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" IWYU_TOOL_VERSION "${IWYU_TOOL_VERSION}") +message(STATUS "🔖 include-what-you-use ${IWYU_TOOL_VERSION} (${IWYU_TOOL})") + +find_program(INFER_TOOL NAMES infer) +execute_process(COMMAND ${INFER_TOOL} --version OUTPUT_VARIABLE INFER_TOOL_VERSION ERROR_VARIABLE INFER_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" INFER_TOOL_VERSION "${INFER_TOOL_VERSION}") +message(STATUS "🔖 Infer ${INFER_TOOL_VERSION} (${INFER_TOOL})") + +find_program(LCOV_TOOL NAMES lcov) +execute_process(COMMAND ${LCOV_TOOL} --version OUTPUT_VARIABLE LCOV_TOOL_VERSION ERROR_VARIABLE LCOV_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" LCOV_TOOL_VERSION "${LCOV_TOOL_VERSION}") +message(STATUS "🔖 LCOV ${LCOV_TOOL_VERSION} (${LCOV_TOOL})") + +find_program(NINJA_TOOL NAMES ninja) +execute_process(COMMAND ${NINJA_TOOL} --version OUTPUT_VARIABLE NINJA_TOOL_VERSION ERROR_VARIABLE NINJA_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" NINJA_TOOL_VERSION "${NINJA_TOOL_VERSION}") +message(STATUS "🔖 Ninja ${NINJA_TOOL_VERSION} (${NINJA_TOOL})") + +find_program(OCLINT_TOOL NAMES oclint-json-compilation-database) +find_program(OCLINT_VERSION_TOOL NAMES oclint) +execute_process(COMMAND ${OCLINT_VERSION_TOOL} --version OUTPUT_VARIABLE OCLINT_TOOL_VERSION ERROR_VARIABLE OCLINT_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" OCLINT_TOOL_VERSION "${OCLINT_TOOL_VERSION}") +message(STATUS "🔖 OCLint ${OCLINT_TOOL_VERSION} (${OCLINT_TOOL})") + +find_program(VALGRIND_TOOL NAMES valgrind) +execute_process(COMMAND ${VALGRIND_TOOL} --version OUTPUT_VARIABLE VALGRIND_TOOL_VERSION ERROR_VARIABLE VALGRIND_TOOL_VERSION) +string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" VALGRIND_TOOL_VERSION "${VALGRIND_TOOL_VERSION}") +message(STATUS "🔖 Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})") + +find_program(GENHTML_TOOL NAMES genhtml) +find_program(PLOG_CONVERTER_TOOL NAMES plog-converter) +find_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer) +find_program(SCAN_BUILD_TOOL NAMES scan-build-15 scan-build-14 scan-build-13 scan-build-12 scan-build-11 scan-build) + +# the individual source files +file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp) + +############################################################################### +# Thorough check with recent compilers +############################################################################### + +# Ignored Clang warnings: +# -Wno-c++98-compat The library targets C++11. +# -Wno-c++98-compat-pedantic The library targets C++11. +# -Wno-deprecated-declarations The library contains annotations for deprecated functions. +# -Wno-extra-semi-stmt The library uses std::assert which triggers this warning. +# -Wno-padded We do not care about padding warnings. +# -Wno-covered-switch-default All switches list all cases and a default case. +# -Wno-weak-vtables The library is header-only. +# -Wreserved-identifier See https://github.com/onqtam/doctest/issues/536. + +set(CLANG_CXXFLAGS + -Werror + -Weverything + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-deprecated-declarations + -Wno-extra-semi-stmt + -Wno-padded + -Wno-covered-switch-default + -Wno-weak-vtables + -Wno-reserved-identifier +) + +# Warning flags determined for GCC 13.0 (experimental) with https://github.com/nlohmann/gcc_flags: +# Ignored GCC warnings: +# -Wno-abi-tag We do not care about ABI tags. +# -Wno-aggregate-return The library uses aggregate returns. +# -Wno-long-long The library uses the long long type to interface with system functions. +# -Wno-namespaces The library uses namespaces. +# -Wno-padded We do not care about padding warnings. +# -Wno-system-headers We do not care about warnings in system headers. +# -Wno-templates The library uses templates. + +set(GCC_CXXFLAGS + -pedantic + -Werror + --all-warnings + --extra-warnings + -W + -WNSObject-attribute + -Wno-abi-tag + -Waddress + -Waddress-of-packed-member + -Wno-aggregate-return + -Waggressive-loop-optimizations + -Waligned-new=all + -Wall + -Walloc-zero + -Walloca + -Wanalyzer-double-fclose + -Wanalyzer-double-free + -Wanalyzer-exposure-through-output-file + -Wanalyzer-file-leak + -Wanalyzer-free-of-non-heap + -Wanalyzer-malloc-leak + -Wanalyzer-mismatching-deallocation + -Wanalyzer-null-argument + -Wanalyzer-null-dereference + -Wanalyzer-possible-null-argument + -Wanalyzer-possible-null-dereference + -Wanalyzer-shift-count-negative + -Wanalyzer-shift-count-overflow + -Wanalyzer-stale-setjmp-buffer + -Wanalyzer-tainted-allocation-size + -Wanalyzer-tainted-array-index + -Wanalyzer-tainted-divisor + -Wanalyzer-tainted-offset + -Wanalyzer-tainted-size + -Wanalyzer-too-complex + -Wanalyzer-unsafe-call-within-signal-handler + -Wanalyzer-use-after-free + -Wanalyzer-use-of-pointer-in-stale-stack-frame + -Wanalyzer-use-of-uninitialized-value + -Wanalyzer-va-arg-type-mismatch + -Wanalyzer-va-list-exhausted + -Wanalyzer-va-list-leak + -Wanalyzer-va-list-use-after-va-end + -Wanalyzer-write-to-const + -Wanalyzer-write-to-string-literal + -Warith-conversion + -Warray-bounds=2 + -Warray-compare + -Warray-parameter=2 + -Wattribute-alias=2 + -Wattribute-warning + -Wattributes + -Wbool-compare + -Wbool-operation + -Wbuiltin-declaration-mismatch + -Wbuiltin-macro-redefined + -Wc++0x-compat + -Wc++11-compat + -Wc++11-extensions + -Wc++14-compat + -Wc++14-extensions + -Wc++17-compat + -Wc++17-extensions + -Wc++1z-compat + -Wc++20-compat + -Wc++20-extensions + -Wc++23-extensions + -Wc++2a-compat + -Wcannot-profile + -Wcast-align + -Wcast-align=strict + -Wcast-function-type + -Wcast-qual + -Wcatch-value=3 + -Wchar-subscripts + -Wclass-conversion + -Wclass-memaccess + -Wclobbered + -Wcomma-subscript + -Wcomment + -Wcomments + -Wconditionally-supported + -Wconversion + -Wconversion-null + -Wcoverage-invalid-line-number + -Wcoverage-mismatch + -Wcpp + -Wctad-maybe-unsupported + -Wctor-dtor-privacy + -Wdangling-else + -Wdangling-pointer=2 + -Wdate-time + -Wdelete-incomplete + -Wdelete-non-virtual-dtor + -Wdeprecated + -Wdeprecated-copy + -Wdeprecated-copy-dtor + -Wdeprecated-declarations + -Wdeprecated-enum-enum-conversion + -Wdeprecated-enum-float-conversion + -Wdisabled-optimization + -Wdiv-by-zero + -Wdouble-promotion + -Wduplicated-branches + -Wduplicated-cond + -Weffc++ + -Wempty-body + -Wendif-labels + -Wenum-compare + -Wenum-conversion + -Wexceptions + -Wexpansion-to-defined + -Wextra + -Wextra-semi + -Wfloat-conversion + -Wfloat-equal + -Wformat-diag + -Wformat-overflow=2 + -Wformat-signedness + -Wformat-truncation=2 + -Wformat=2 + -Wframe-address + -Wfree-nonheap-object + -Whsa + -Wif-not-aligned + -Wignored-attributes + -Wignored-qualifiers + -Wimplicit-fallthrough=5 + -Winaccessible-base + -Winfinite-recursion + -Winherited-variadic-ctor + -Winit-list-lifetime + -Winit-self + -Winline + -Wint-in-bool-context + -Wint-to-pointer-cast + -Winterference-size + -Winvalid-imported-macros + -Winvalid-memory-model + -Winvalid-offsetof + -Winvalid-pch + -Wliteral-suffix + -Wlogical-not-parentheses + -Wlogical-op + -Wno-long-long + -Wlto-type-mismatch + -Wmain + -Wmaybe-uninitialized + -Wmemset-elt-size + -Wmemset-transposed-args + -Wmisleading-indentation + -Wmismatched-dealloc + -Wmismatched-new-delete + -Wmismatched-tags + -Wmissing-attributes + -Wmissing-braces + -Wmissing-declarations + -Wmissing-field-initializers + -Wmissing-include-dirs + -Wmissing-profile + -Wmissing-requires + -Wmissing-template-keyword + -Wmultichar + -Wmultiple-inheritance + -Wmultistatement-macros + -Wno-namespaces + -Wnarrowing + -Wnoexcept + -Wnoexcept-type + -Wnon-template-friend + -Wnon-virtual-dtor + -Wnonnull + -Wnonnull-compare + -Wnormalized=nfkc + -Wnull-dereference + -Wodr + -Wold-style-cast + -Wopenacc-parallelism + -Wopenmp-simd + -Woverflow + -Woverlength-strings + -Woverloaded-virtual + -Wpacked + -Wpacked-bitfield-compat + -Wpacked-not-aligned + -Wno-padded + -Wparentheses + -Wpedantic + -Wpessimizing-move + -Wplacement-new=2 + -Wpmf-conversions + -Wpointer-arith + -Wpointer-compare + -Wpragmas + -Wprio-ctor-dtor + -Wpsabi + -Wrange-loop-construct + -Wredundant-decls + -Wredundant-move + -Wredundant-tags + -Wregister + -Wreorder + -Wrestrict + -Wreturn-local-addr + -Wreturn-type + -Wscalar-storage-order + -Wsequence-point + -Wshadow=compatible-local + -Wshadow=global + -Wshadow=local + -Wshift-count-negative + -Wshift-count-overflow + -Wshift-negative-value + -Wshift-overflow=2 + -Wsign-compare + -Wsign-conversion + -Wsign-promo + -Wsized-deallocation + -Wsizeof-array-argument + -Wsizeof-array-div + -Wsizeof-pointer-div + -Wsizeof-pointer-memaccess + -Wstack-protector + -Wstrict-aliasing=3 + -Wstrict-null-sentinel + -Wno-strict-overflow + -Wstring-compare + -Wstringop-overflow=4 + -Wstringop-overread + -Wstringop-truncation + -Wsubobject-linkage + -Wsuggest-attribute=cold + -Wsuggest-attribute=const + -Wsuggest-attribute=format + -Wsuggest-attribute=malloc + -Wsuggest-attribute=noreturn + -Wsuggest-attribute=pure + -Wsuggest-final-methods + -Wsuggest-final-types + -Wsuggest-override + -Wswitch + -Wswitch-bool + -Wswitch-default + -Wswitch-enum + -Wswitch-outside-range + -Wswitch-unreachable + -Wsync-nand + -Wsynth + -Wno-system-headers + -Wtautological-compare + -Wno-templates + -Wterminate + -Wtrampolines + -Wtrigraphs + -Wtrivial-auto-var-init + -Wtsan + -Wtype-limits + -Wundef + -Wuninitialized + -Wunknown-pragmas + -Wunreachable-code + -Wunsafe-loop-optimizations + -Wunused + -Wunused-but-set-parameter + -Wunused-but-set-variable + -Wunused-const-variable=2 + -Wunused-function + -Wunused-label + -Wunused-local-typedefs + -Wunused-macros + -Wunused-parameter + -Wunused-result + -Wunused-value + -Wunused-variable + -Wuse-after-free=3 + -Wuseless-cast + -Wvarargs + -Wvariadic-macros + -Wvector-operation-performance + -Wvexing-parse + -Wvirtual-inheritance + -Wvirtual-move-assign + -Wvla + -Wvla-parameter + -Wvolatile + -Wvolatile-register-var + -Wwrite-strings + -Wzero-as-null-pointer-constant + -Wzero-length-bounds +) + +add_custom_target(ci_test_gcc + COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc + COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with GCC using maximal warning flags" +) + +add_custom_target(ci_test_clang + COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang + COMMAND cd ${PROJECT_BINARY_DIR}/build_clang && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with Clang using maximal warning flags" +) + +############################################################################### +# Different C++ Standards. +############################################################################### + +foreach(CXX_STANDARD 11 14 17 20) + add_custom_target(ci_test_gcc_cxx${CXX_STANDARD} + COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -DJSON_TestStandards=${CXX_STANDARD} + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} + COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with GCC for C++${CXX_STANDARD}" + ) + + add_custom_target(ci_test_clang_cxx${CXX_STANDARD} + COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -DJSON_TestStandards=${CXX_STANDARD} + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} + COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with Clang for C++${CXX_STANDARD}" + ) +endforeach() + +############################################################################### +# Disable exceptions. +############################################################################### + +add_custom_target(ci_test_noexceptions + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DCMAKE_CXX_FLAGS=-DJSON_NOEXCEPTION -DDOCTEST_TEST_FILTER=--no-throw + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noexceptions + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noexceptions + COMMAND cd ${PROJECT_BINARY_DIR}/build_noexceptions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with exceptions switched off" +) + +############################################################################### +# Disable implicit conversions. +############################################################################### + +add_custom_target(ci_test_noimplicitconversions + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_ImplicitConversions=OFF + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noimplicitconversions + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noimplicitconversions + COMMAND cd ${PROJECT_BINARY_DIR}/build_noimplicitconversions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with implicit conversions switched off" +) + +############################################################################### +# Enable improved diagnostics. +############################################################################### + +add_custom_target(ci_test_diagnostics + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_Diagnostics=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_diagnostics + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_diagnostics + COMMAND cd ${PROJECT_BINARY_DIR}/build_diagnostics && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with improved diagnostics enabled" +) + +############################################################################### +# Enable legacy discarded value comparison. +############################################################################### + +add_custom_target(ci_test_legacycomparison + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_LegacyDiscardedValueComparison=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_legacycomparison + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_legacycomparison + COMMAND cd ${PROJECT_BINARY_DIR}/build_legacycomparison && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with legacy discarded value comparison enabled" +) + +############################################################################### +# Disable global UDLs. +############################################################################### + +add_custom_target(ci_test_noglobaludls + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_GlobalUDLs=OFF + -DCMAKE_CXX_FLAGS=-DJSON_TEST_NO_GLOBAL_UDLS + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noglobaludls + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noglobaludls + COMMAND cd ${PROJECT_BINARY_DIR}/build_noglobaludls && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with global UDLs disabled" +) + +############################################################################### +# Coverage. +############################################################################### + +add_custom_target(ci_test_coverage + COMMAND CXX=g++ ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="--coverage;-fprofile-arcs;-ftest-coverage" + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage + COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + + COMMAND CXX=g++ ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="-m32;--coverage;-fprofile-arcs;-ftest-coverage" + -DJSON_BuildTests=ON -DJSON_32bitTest=ONLY + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage32 + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage32 + COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage32 && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + + COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc lcov_branch_coverage=1 + COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc lcov_branch_coverage=1 + COMMAND ${CMAKE_SOURCE_DIR}/tests/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept + COMMAND genhtml --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept + + COMMENT "Compile and test with coverage" +) + +############################################################################### +# Sanitizers. +############################################################################### + +set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base") + +add_custom_target(ci_test_clang_sanitizer + COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_sanitizer + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_sanitizer + COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_sanitizer && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test with sanitizers" +) + +############################################################################### +# Check if header is amalgamated and sources are properly indented. +############################################################################### + +set(ASTYLE_FLAGS --style=allman --indent=spaces=4 --indent-modifiers --indent-switches --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-oper --pad-header --align-pointer=type --align-reference=type --add-brackets --convert-tabs --close-templates --lineend=linux --preserve-date --formatted) + +file(GLOB_RECURSE INDENT_FILES + ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp + ${PROJECT_SOURCE_DIR}/tests/src/*.cpp + ${PROJECT_SOURCE_DIR}/tests/src/*.hpp + ${PROJECT_SOURCE_DIR}/tests/benchmarks/src/benchmarks.cpp + ${PROJECT_SOURCE_DIR}/docs/examples/*.cpp +) + +set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann) +set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate) +add_custom_target(ci_test_amalgamation + COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ + COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~ + COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~ + + COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s . + COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s . + COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} --suffix=none --quiet ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp + + COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp + COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp + + COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} ${INDENT_FILES} + COMMAND for FILE in `find . -name '*.orig'`\; do false \; done + + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMENT "Check amalgamation and indentation" +) + +############################################################################### +# Build and test using the amalgamated header +############################################################################### + +add_custom_target(ci_test_single_header + COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_MultipleHeaders=OFF -DJSON_FastTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_single_header + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_single_header + COMMAND cd ${PROJECT_BINARY_DIR}/build_single_header && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test single-header version" +) + +############################################################################### +# Valgrind. +############################################################################### + +add_custom_target(ci_test_valgrind + COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_Valgrind=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_valgrind + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_valgrind + COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --parallel ${N} --output-on-failure + COMMENT "Compile and test with Valgrind" +) + +############################################################################### +# Check code with Clang Static Analyzer. +############################################################################### + +set(CLANG_ANALYZER_CHECKS "fuchsia.HandleChecker,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,optin.cplusplus.UninitializedObject,optin.cplusplus.VirtualCall,optin.mpi.MPI-Checker,optin.osx.OSObjectCStyleCast,optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,optin.osx.cocoa.localizability.NonLocalizedStringChecker,optin.performance.GCDAntipattern,optin.performance.Padding,optin.portability.UnixAPI,security.FloatLoopCounter,security.insecureAPI.DeprecatedOrUnsafeBufferHandling,security.insecureAPI.bcmp,security.insecureAPI.bcopy,security.insecureAPI.bzero,security.insecureAPI.rand,security.insecureAPI.strcpy,valist.CopyToSelf,valist.Uninitialized,valist.Unterminated,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,core.CallAndMessage,core.DivideZero,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.VLASize,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.PlacementNew,cplusplus.PureVirtualCall,deadcode.DeadStores,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,osx.API,osx.MIG,osx.NumberObjectConversion,osx.OSObjectRetainCount,osx.ObjCProperty,osx.SecKeychainAPI,osx.cocoa.AtSync,osx.cocoa.AutoreleaseWrite,osx.cocoa.ClassRelease,osx.cocoa.Dealloc,osx.cocoa.IncompatibleMethodTypes,osx.cocoa.Loops,osx.cocoa.MissingSuperCall,osx.cocoa.NSAutoreleasePool,osx.cocoa.NSError,osx.cocoa.NilArg,osx.cocoa.NonNilReturnValue,osx.cocoa.ObjCGenerics,osx.cocoa.RetainCount,osx.cocoa.RunLoopAutoreleaseLeak,osx.cocoa.SelfInit,osx.cocoa.SuperDealloc,osx.cocoa.UnusedIvars,osx.cocoa.VariadicMethodTypes,osx.coreFoundation.CFError,osx.coreFoundation.CFNumber,osx.coreFoundation.CFRetainRelease,osx.coreFoundation.containers.OutOfBounds,osx.coreFoundation.containers.PointerSizedValues,security.insecureAPI.UncheckedReturn,security.insecureAPI.decodeValueOfObjCType,security.insecureAPI.getpw,security.insecureAPI.gets,security.insecureAPI.mkstemp,security.insecureAPI.mktemp,security.insecureAPI.vfork,unix.API,unix.Malloc,unix.MallocSizeof,unix.MismatchedDeallocator,unix.Vfork,unix.cstring.BadSizeArg,unix.cstring.NullArg") + +add_custom_target(ci_clang_analyze + COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_analyze + COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_analyze && ${SCAN_BUILD_TOOL} -enable-checker ${CLANG_ANALYZER_CHECKS} --use-c++=${CLANG_TOOL} -analyze-headers -o ${PROJECT_BINARY_DIR}/report ninja + COMMENT "Check code with Clang Analyzer" +) + +############################################################################### +# Check code with Cppcheck. +############################################################################### + +add_custom_target(ci_cppcheck + COMMAND ${CPPCHECK_TOOL} --enable=warning --suppress=missingReturn --inline-suppr --inconclusive --force --std=c++11 ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp --error-exitcode=1 + COMMENT "Check code with Cppcheck" +) + +############################################################################### +# Check code with cpplint. +############################################################################### + +add_custom_target(ci_cpplint + COMMAND ${Python3_EXECUTABLE} -mvenv venv_cpplint + COMMAND venv_cpplint/bin/pip3 --quiet install cpplint + COMMAND venv_cpplint/bin/cpplint --filter=-whitespace,-legal,-runtime/references,-runtime/explicit,-runtime/indentation_namespace,-readability/casting,-readability/nolint --quiet --recursive ${SRC_FILES} + COMMENT "Check code with cpplint" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} +) + +############################################################################### +# Check code with OCLint. +############################################################################### + +file(COPY ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp DESTINATION ${PROJECT_BINARY_DIR}/src_single) +file(RENAME ${PROJECT_BINARY_DIR}/src_single/json.hpp ${PROJECT_BINARY_DIR}/src_single/all.cpp) +file(APPEND "${PROJECT_BINARY_DIR}/src_single/all.cpp" "\n\nint main()\n{}\n") + +add_executable(single_all ${PROJECT_BINARY_DIR}/src_single/all.cpp) +target_compile_features(single_all PRIVATE cxx_std_11) + +add_custom_target(ci_oclint + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -DJSON_BuildTests=OFF -DJSON_CI=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_oclint + COMMAND ${OCLINT_TOOL} -i ${PROJECT_BINARY_DIR}/build_oclint/src_single/all.cpp -p ${PROJECT_BINARY_DIR}/build_oclint -- + -report-type html -enable-global-analysis --max-priority-1=0 --max-priority-2=1000 --max-priority-3=2000 + --disable-rule=MultipleUnaryOperator + --disable-rule=DoubleNegative + --disable-rule=ShortVariableName + --disable-rule=GotoStatement + --disable-rule=LongLine + -o ${PROJECT_BINARY_DIR}/build_oclint/oclint_report.html + COMMENT "Check code with OCLint" +) + +############################################################################### +# Check code with Clang-Tidy. +############################################################################### + +add_custom_target(ci_clang_tidy + COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_CLANG_TIDY=${CLANG_TIDY_TOOL} + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_tidy + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_tidy + COMMENT "Check code with Clang-Tidy" +) + +############################################################################### +# Check code with PVS-Studio Analyzer . +############################################################################### + +add_custom_target(ci_pvs_studio + COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -DJSON_BuildTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_pvs_studio + COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PVS_STUDIO_ANALYZER_TOOL} analyze -j 10 + COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PLOG_CONVERTER_TOOL} -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs + COMMENT "Check code with PVS Studio" +) + +############################################################################### +# Check code with Infer static analyzer. +############################################################################### + +add_custom_target(ci_infer + COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer + COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON + COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make + COMMENT "Check code with Infer" +) + +############################################################################### +# Run test suite with previously downloaded test data. +############################################################################### + +add_custom_target(ci_offline_testdata + COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_offline_testdata/test_data + COMMAND cd ${PROJECT_BINARY_DIR}/build_offline_testdata/test_data && ${GIT_TOOL} clone -c advice.detachedHead=false --branch v3.1.0 https://github.com/nlohmann/json_test_data.git --quiet --depth 1 + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_TestDataDirectory=${PROJECT_BINARY_DIR}/build_offline_testdata/test_data/json_test_data + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_offline_testdata + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_offline_testdata + COMMAND cd ${PROJECT_BINARY_DIR}/build_offline_testdata && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Check code with previously downloaded test data" +) + +############################################################################### +# Run test suite when project was not checked out from Git +############################################################################### + +add_custom_target(ci_non_git_tests + COMMAND git config --global --add safe.directory ${PROJECT_SOURCE_DIR} + COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_non_git_tests/sources + COMMAND cd ${PROJECT_SOURCE_DIR} && for FILE in `${GIT_TOOL} ls-tree --name-only HEAD`\; do cp -r $$FILE ${PROJECT_BINARY_DIR}/build_non_git_tests/sources \; done + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -S${PROJECT_BINARY_DIR}/build_non_git_tests/sources -B${PROJECT_BINARY_DIR}/build_non_git_tests + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_non_git_tests + COMMAND cd ${PROJECT_BINARY_DIR}/build_non_git_tests && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE git_required --output-on-failure + COMMENT "Check code when project was not checked out from Git" +) + +############################################################################### +# Run test suite and exclude tests that change installed files +############################################################################### + +add_custom_target(ci_reproducible_tests + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_reproducible_tests + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_reproducible_tests + COMMAND cd ${PROJECT_BINARY_DIR}/build_reproducible_tests && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE not_reproducible --output-on-failure + COMMENT "Check code and exclude tests that change installed files" +) + +############################################################################### +# Check if every header in the include folder includes sufficient headers to +# be compiled individually. +############################################################################### + +set(iwyu_path_and_options ${IWYU_TOOL} -Xiwyu --max_line_length=300) + +foreach(SRC_FILE ${SRC_FILES}) + # get relative path of the header file + file(RELATIVE_PATH RELATIVE_SRC_FILE "${PROJECT_SOURCE_DIR}/include/nlohmann" "${SRC_FILE}") + # replace slashes and strip suffix + string(REPLACE "/" "_" RELATIVE_SRC_FILE "${RELATIVE_SRC_FILE}") + string(REPLACE ".hpp" "" RELATIVE_SRC_FILE "${RELATIVE_SRC_FILE}") + # create code file + file(WRITE "${PROJECT_BINARY_DIR}/src_single/${RELATIVE_SRC_FILE}.cpp" "#include \"${SRC_FILE}\" // IWYU pragma: keep\n\nint main()\n{}\n") + # create executable + add_executable(single_${RELATIVE_SRC_FILE} EXCLUDE_FROM_ALL ${PROJECT_BINARY_DIR}/src_single/${RELATIVE_SRC_FILE}.cpp) + target_include_directories(single_${RELATIVE_SRC_FILE} PRIVATE ${PROJECT_SOURCE_DIR}/include) + target_compile_features(single_${RELATIVE_SRC_FILE} PRIVATE cxx_std_11) + set_property(TARGET single_${RELATIVE_SRC_FILE} PROPERTY CXX_INCLUDE_WHAT_YOU_USE "${iwyu_path_and_options}") + # remember binary for ci_single_binaries target + list(APPEND single_binaries single_${RELATIVE_SRC_FILE}) +endforeach() + +add_custom_target(ci_single_binaries + DEPENDS ${single_binaries} + COMMENT "Check if headers are self-contained" +) + +############################################################################### +# Benchmarks +############################################################################### + +add_custom_target(ci_benchmarks + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Release -GNinja + -S${PROJECT_SOURCE_DIR}/benchmarks -B${PROJECT_BINARY_DIR}/build_benchmarks + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_benchmarks --target json_benchmarks + COMMAND cd ${PROJECT_BINARY_DIR}/build_benchmarks && ./json_benchmarks + COMMENT "Run benchmarks" +) + +############################################################################### +# CMake flags +############################################################################### + +function(ci_get_cmake version var) + set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}/bin/cmake) + add_custom_command( + OUTPUT ${${var}} + COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}.tar.gz + COMMAND tar xfz cmake-${version}.tar.gz + COMMAND rm cmake-${version}.tar.gz + COMMAND ${CMAKE_COMMAND} -S cmake-${version} -B cmake-${version} + COMMAND ${CMAKE_COMMAND} --build cmake-${version} --parallel 10 + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Download CMake ${version}" + ) + set(${var} ${${var}} PARENT_SCOPE) +endfunction() + +ci_get_cmake(3.1.0 CMAKE_3_1_0_BINARY) +ci_get_cmake(3.13.0 CMAKE_3_13_0_BINARY) + +set(JSON_CMAKE_FLAGS_3_1_0 JSON_Diagnostics JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization + JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind) +set(JSON_CMAKE_FLAGS_3_13_0 JSON_BuildTests) + +function(ci_add_cmake_flags_targets flag min_version) + string(TOLOWER "ci_cmake_flag_${flag}" flag_target) + string(REPLACE . _ min_version_var ${min_version}) + set(cmake_binary ${CMAKE_${min_version_var}_BINARY}) + add_custom_target(${flag_target} + COMMENT "Check CMake flag ${flag} (CMake ${CMAKE_VERSION})" + COMMAND ${CMAKE_COMMAND} + -Werror=dev + -D${flag}=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${flag_target} + ) + add_custom_target(${flag_target}_${min_version_var} + COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${min_version})" + COMMAND mkdir -pv ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var} + COMMAND cd ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var} + && ${cmake_binary} -Werror=dev ${PROJECT_SOURCE_DIR} -D${flag}=ON + DEPENDS ${cmake_binary} + ) + list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${flag_target}_${min_version_var}) + list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${flag_target} ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}) + set(JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGETS} PARENT_SCOPE) + set(JSON_CMAKE_FLAG_BUILD_DIRS ${JSON_CMAKE_FLAG_BUILD_DIRS} PARENT_SCOPE) +endfunction() + +foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_3_1_0}) + ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 3.1.0) +endforeach() + +foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_3_13_0}) + ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 3.13.0) +endforeach() + +add_custom_target(ci_cmake_flags + DEPENDS ${JSON_CMAKE_FLAG_TARGETS} + COMMENT "Check CMake flags" +) + +############################################################################### +# Use more installed compilers. +############################################################################### + +foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 g++-11 clang++-3.5 clang++-3.6 clang++-3.7 clang++-3.8 clang++-3.9 clang++-4.0 clang++-5.0 clang++-6.0 clang++-7 clang++-8 clang++-9 clang++-10 clang++-11 clang++-12 clang++-13 clang++-14) + find_program(COMPILER_TOOL NAMES ${COMPILER}) + if (COMPILER_TOOL) + unset(ADDITIONAL_FLAGS) + + add_custom_target(ci_test_compiler_${COMPILER} + COMMAND CXX=${COMPILER} ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} + ${ADDITIONAL_FLAGS} + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} + COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure + COMMENT "Compile and test with ${COMPILER}" + ) + endif() + unset(COMPILER_TOOL CACHE) +endforeach() + +add_custom_target(ci_test_compiler_default + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_default + ${ADDITIONAL_FLAGS} + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_default --parallel ${N} + COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" -LE git_required --output-on-failure + COMMENT "Compile and test with default C++ compiler" +) + +############################################################################### +# CUDA example +############################################################################### + +add_custom_target(ci_cuda_example + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DCMAKE_CUDA_HOST_COMPILER=g++-8 + -S${PROJECT_SOURCE_DIR}/tests/cuda_example -B${PROJECT_BINARY_DIR}/build_cuda_example + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example +) + +############################################################################### +# Intel C++ Compiler +############################################################################### + +add_custom_target(ci_icpc + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc + -DJSON_BuildTests=ON -DJSON_FastTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpc + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpc + COMMAND cd ${PROJECT_BINARY_DIR}/build_icpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure + COMMENT "Compile and test with ICPC" +) + +############################################################################### +# test documentation +############################################################################### + +add_custom_target(ci_test_examples + COMMAND make CXX="${GCC_TOOL}" check_output_portable -j8 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs + COMMENT "Check that all examples compile and create the desired output" +) + +add_custom_target(ci_test_api_documentation + COMMAND ${Python3_EXECUTABLE} scripts/check_structure.py + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs/mkdocs + COMMENT "Lint the API documentation" +) + +############################################################################### +# Clean up all generated files. +############################################################################### + +add_custom_target(ci_clean + COMMAND rm -fr ${PROJECT_BINARY_DIR}/build_* cmake-3.1.0-Darwin64 ${JSON_CMAKE_FLAG_BUILD_DIRS} ${single_binaries} + COMMENT "Clean generated directories" +) diff --git a/json-develop/cmake/config.cmake.in b/json-develop/cmake/config.cmake.in new file mode 100644 index 0000000..9a17a7d --- /dev/null +++ b/json-develop/cmake/config.cmake.in @@ -0,0 +1,15 @@ +include(FindPackageHandleStandardArgs) +set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE}) +find_package_handle_standard_args(@PROJECT_NAME@ CONFIG_MODE) + +if(NOT TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake") + if((NOT TARGET @NLOHMANN_JSON_TARGET_NAME@) AND + (NOT @PROJECT_NAME@_FIND_VERSION OR + @PROJECT_NAME@_FIND_VERSION VERSION_LESS 3.2.0)) + add_library(@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED) + set_target_properties(@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES + INTERFACE_LINK_LIBRARIES @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ + ) + endif() +endif() diff --git a/json-develop/cmake/download_test_data.cmake b/json-develop/cmake/download_test_data.cmake new file mode 100644 index 0000000..1bb998d --- /dev/null +++ b/json-develop/cmake/download_test_data.cmake @@ -0,0 +1,56 @@ +set(JSON_TEST_DATA_URL https://github.com/nlohmann/json_test_data) +set(JSON_TEST_DATA_VERSION 3.1.0) + +# if variable is set, use test data from given directory rather than downloading them +if(JSON_TestDataDirectory) + message(STATUS "Using test data in ${JSON_TestDataDirectory}.") + add_custom_target(download_test_data) + file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp "#define TEST_DATA_DIRECTORY \"${JSON_TestDataDirectory}\"\n") +else() + find_package(Git) + # target to download test data + add_custom_target(download_test_data + COMMAND test -d json_test_data || ${GIT_EXECUTABLE} clone -c advice.detachedHead=false --branch v${JSON_TEST_DATA_VERSION} ${JSON_TEST_DATA_URL}.git --quiet --depth 1 + COMMENT "Downloading test data from ${JSON_TEST_DATA_URL} (v${JSON_TEST_DATA_VERSION})" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + # create a header with the path to the downloaded test data + file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp "#define TEST_DATA_DIRECTORY \"${CMAKE_BINARY_DIR}/json_test_data\"\n") +endif() + +# determine the operating system (for debug and support purposes) +find_program(UNAME_COMMAND uname) +find_program(VER_COMMAND ver) +find_program(LSB_RELEASE_COMMAND lsb_release) +find_program(SW_VERS_COMMAND sw_vers) +set(OS_VERSION_STRINGS "${CMAKE_SYSTEM}") +if (VER_COMMAND) + execute_process(COMMAND ${VER_COMMAND} OUTPUT_VARIABLE VER_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE) + set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${VER_COMMAND_RESULT}") +endif() +if (SW_VERS_COMMAND) + execute_process(COMMAND ${SW_VERS_COMMAND} OUTPUT_VARIABLE SW_VERS_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + string(REGEX REPLACE "[ ]*\n" "; " SW_VERS_COMMAND_RESULT "${SW_VERS_COMMAND_RESULT}") + set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${SW_VERS_COMMAND_RESULT}") +endif() +if (LSB_RELEASE_COMMAND) + execute_process(COMMAND ${LSB_RELEASE_COMMAND} -a OUTPUT_VARIABLE LSB_RELEASE_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + string(REGEX REPLACE "[ ]*\n" "; " LSB_RELEASE_COMMAND_RESULT "${LSB_RELEASE_COMMAND_RESULT}") + set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${LSB_RELEASE_COMMAND_RESULT}") +endif() +if (UNAME_COMMAND) + execute_process(COMMAND ${UNAME_COMMAND} -a OUTPUT_VARIABLE UNAME_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + set(OS_VERSION_STRINGS "${OS_VERSION_STRINGS}; ${UNAME_COMMAND_RESULT}") +endif() + +message(STATUS "Operating system: ${OS_VERSION_STRINGS}") + +# determine the compiler (for debug and support purposes) +if (MSVC) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} OUTPUT_VARIABLE CXX_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE CXX_VERSION_RESULT ERROR_STRIP_TRAILING_WHITESPACE) + set(CXX_VERSION_RESULT "${CXX_VERSION_RESULT}; MSVC_VERSION=${MSVC_VERSION}; MSVC_TOOLSET_VERSION=${MSVC_TOOLSET_VERSION}") +else() + execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE CXX_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +string(REGEX REPLACE "[ ]*\n" "; " CXX_VERSION_RESULT "${CXX_VERSION_RESULT}") +message(STATUS "Compiler: ${CXX_VERSION_RESULT}") diff --git a/json-develop/cmake/nlohmann_jsonConfigVersion.cmake.in b/json-develop/cmake/nlohmann_jsonConfigVersion.cmake.in new file mode 100644 index 0000000..1091085 --- /dev/null +++ b/json-develop/cmake/nlohmann_jsonConfigVersion.cmake.in @@ -0,0 +1,20 @@ +# This is essentially cmake's BasicConfigVersion-SameMajorVersion.cmake.in but +# without the 32/64-bit check. Since json is a header-only library, it doesn't +# matter if it was built on a different platform than what it is used on (see +# https://github.com/nlohmann/json/issues/1697). +set(PACKAGE_VERSION "@PROJECT_VERSION@") + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL "@PROJECT_VERSION_MAJOR@") + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/json-develop/cmake/pkg-config.pc.in b/json-develop/cmake/pkg-config.pc.in new file mode 100644 index 0000000..d36317f --- /dev/null +++ b/json-develop/cmake/pkg-config.pc.in @@ -0,0 +1,4 @@ +Name: ${PROJECT_NAME} +Description: JSON for Modern C++ +Version: ${PROJECT_VERSION} +Cflags: -I${CMAKE_INSTALL_FULL_INCLUDEDIR} diff --git a/json-develop/cmake/scripts/gen_bazel_build_file.cmake b/json-develop/cmake/scripts/gen_bazel_build_file.cmake new file mode 100644 index 0000000..e754d38 --- /dev/null +++ b/json-develop/cmake/scripts/gen_bazel_build_file.cmake @@ -0,0 +1,24 @@ +# generate Bazel BUILD file + +set(PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/../..") +set(BUILD_FILE "${PROJECT_ROOT}/BUILD.bazel") + +file(GLOB_RECURSE HEADERS LIST_DIRECTORIES false RELATIVE "${PROJECT_ROOT}" "include/*.hpp") + +file(WRITE "${BUILD_FILE}" [=[ +cc_library( + name = "json", + hdrs = [ +]=]) + +foreach(header ${HEADERS}) + file(APPEND "${BUILD_FILE}" " \"${header}\",\n") +endforeach() + +file(APPEND "${BUILD_FILE}" [=[ + ], + includes = ["include"], + visibility = ["//visibility:public"], + alwayslink = True, +) +]=]) diff --git a/json-develop/cmake/test.cmake b/json-develop/cmake/test.cmake new file mode 100644 index 0000000..7105b97 --- /dev/null +++ b/json-develop/cmake/test.cmake @@ -0,0 +1,273 @@ +set(_json_test_cmake_list_file ${CMAKE_CURRENT_LIST_FILE}) + +############################################################################# +# download test data +############################################################################# + +include(download_test_data) + +# test fixture to download test data +add_test(NAME "download_test_data" COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} + --target download_test_data +) +set_tests_properties(download_test_data PROPERTIES FIXTURES_SETUP TEST_DATA) + +if(JSON_Valgrind) + find_program(CMAKE_MEMORYCHECK_COMMAND valgrind) + message(STATUS "Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})") + set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full") + separate_arguments(memcheck_command) +endif() + +############################################################################# +# detect standard support +############################################################################# + +# C++11 is the minimum required +set(compiler_supports_cpp_11 TRUE) + +foreach(feature ${CMAKE_CXX_COMPILE_FEATURES}) + if (${feature} STREQUAL cxx_std_14) + set(compiler_supports_cpp_14 TRUE) + elseif (${feature} STREQUAL cxx_std_17) + set(compiler_supports_cpp_17 TRUE) + elseif (${feature} STREQUAL cxx_std_20) + set(compiler_supports_cpp_20 TRUE) + elseif (${feature} STREQUAL cxx_std_23) + set(compiler_supports_cpp_23 TRUE) + endif() +endforeach() + +############################################################################# +# test functions +############################################################################# + +############################################################################# +# json_test_set_test_options( +# all| +# [CXX_STANDARDS all|...] +# [COMPILE_DEFINITIONS ...] +# [COMPILE_FEATURES ...] +# [COMPILE_OPTIONS ...] +# [LINK_LIBRARIES ...] +# [LINK_OPTIONS ...] +# [TEST_PROPERTIES ...]) +# +# Supply test- and standard-specific build settings and/or test properties. +# Specify multiple tests using a list e.g., "test-foo;test-bar". +# +# Must be called BEFORE the test is created. +############################################################################# + +function(json_test_set_test_options tests) + cmake_parse_arguments(args "" "" + "CXX_STANDARDS;COMPILE_DEFINITIONS;COMPILE_FEATURES;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS;TEST_PROPERTIES" + ${ARGN}) + + if(NOT args_CXX_STANDARDS) + set(args_CXX_STANDARDS "all") + endif() + + foreach(test ${tests}) + if("${test}" STREQUAL "all") + set(test "") + endif() + + foreach(cxx_standard ${args_CXX_STANDARDS}) + if("${cxx_standard}" STREQUAL "all") + if("${test}" STREQUAL "") + message(FATAL_ERROR "Not supported. Change defaults in: ${_json_test_cmake_list_file}") + endif() + set(test_interface _json_test_interface_${test}) + else() + set(test_interface _json_test_interface_${test}_cpp_${cxx_standard}) + endif() + + if(NOT TARGET ${test_interface}) + add_library(${test_interface} INTERFACE) + endif() + + target_compile_definitions(${test_interface} INTERFACE ${args_COMPILE_DEFINITIONS}) + target_compile_features(${test_interface} INTERFACE ${args_COMPILE_FEATURES}) + target_compile_options(${test_interface} INTERFACE ${args_COMPILE_OPTIONS}) + target_link_libraries (${test_interface} INTERFACE ${args_LINK_LIBRARIES}) + target_link_options(${test_interface} INTERFACE ${args_LINK_OPTIONS}) + #set_target_properties(${test_interface} PROPERTIES JSON_TEST_PROPERTIES "${args_TEST_PROPERTIES}") + set_property(DIRECTORY PROPERTY + ${test_interface}_TEST_PROPERTIES "${args_TEST_PROPERTIES}" + ) + endforeach() + endforeach() +endfunction() + +# for internal use by _json_test_add_test() +function(_json_test_apply_test_properties test_target properties_target) + #get_target_property(test_properties ${properties_target} JSON_TEST_PROPERTIES) + get_property(test_properties DIRECTORY PROPERTY ${properties_target}_TEST_PROPERTIES) + if(test_properties) + set_tests_properties(${test_target} PROPERTIES ${test_properties}) + endif() +endfunction() + +# for internal use by json_test_add_test_for() +function(_json_test_add_test test_name file main cxx_standard) + set(test_target ${test_name}_cpp${cxx_standard}) + + if(TARGET ${test_target}) + message(FATAL_ERROR "Target ${test_target} has already been added.") + endif() + + add_executable(${test_target} ${file}) + target_link_libraries(${test_target} PRIVATE ${main}) + + # set and require C++ standard + set_target_properties(${test_target} PROPERTIES + CXX_STANDARD ${cxx_standard} + CXX_STANDARD_REQUIRED ON + ) + + # apply standard-specific build settings + if(TARGET _json_test_interface__cpp_${cxx_standard}) + target_link_libraries(${test_target} PRIVATE _json_test_interface__cpp_${cxx_standard}) + endif() + + # apply test-specific build settings + if(TARGET _json_test_interface_${test_name}) + target_link_libraries(${test_target} PRIVATE _json_test_interface_${test_name}) + endif() + + # apply test- and standard-specific build settings + if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard}) + target_link_libraries(${test_target} PRIVATE + _json_test_interface_${test_name}_cpp_${cxx_standard} + ) + endif() + + if (JSON_FastTests) + add_test(NAME ${test_target} + COMMAND ${test_target} ${DOCTEST_TEST_FILTER} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + else() + add_test(NAME ${test_target} + COMMAND ${test_target} ${DOCTEST_TEST_FILTER} --no-skip + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + endif() + set_tests_properties(${test_target} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA) + + # apply standard-specific test properties + if(TARGET _json_test_interface__cpp_${cxx_standard}) + _json_test_apply_test_properties(${test_target} _json_test_interface__cpp_${cxx_standard}) + endif() + + # apply test-specific test properties + if(TARGET _json_test_interface_${test_name}) + _json_test_apply_test_properties(${test_target} _json_test_interface_${test_name}) + endif() + + # apply test- and standard-specific test properties + if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard}) + _json_test_apply_test_properties(${test_target} + _json_test_interface_${test_name}_cpp_${cxx_standard} + ) + endif() + + if(JSON_Valgrind) + add_test(NAME ${test_target}_valgrind + COMMAND ${memcheck_command} $ ${DOCTEST_TEST_FILTER} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + set_tests_properties(${test_target}_valgrind PROPERTIES + LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA + ) + endif() +endfunction() + +############################################################################# +# json_test_add_test_for( +# +# [NAME ] +# MAIN
+# [CXX_STANDARDS ...] [FORCE]) +# +# Given a unit-foo.cpp, produces +# +# test-foo_cpp +# +# if C++ standard is supported by the compiler and the +# source file contains JSON_HAS_CPP_. +# Use NAME to override the filename-derived test name. +# Use FORCE to create the test regardless of the file containing +# JSON_HAS_CPP_. +# Test targets are linked against
. +# CXX_STANDARDS defaults to "11". +############################################################################# + +function(json_test_add_test_for file) + cmake_parse_arguments(args "FORCE" "MAIN;NAME" "CXX_STANDARDS" ${ARGN}) + + if("${args_MAIN}" STREQUAL "") + message(FATAL_ERROR "Required argument MAIN
missing.") + endif() + + if("${args_NAME}" STREQUAL "") + get_filename_component(file_basename ${file} NAME_WE) + string(REGEX REPLACE "unit-([^$]+)" "test-\\1" test_name ${file_basename}) + else() + set(test_name ${args_NAME}) + if(NOT test_name MATCHES "test-[^$]+") + message(FATAL_ERROR "Test name must start with 'test-'.") + endif() + endif() + + if("${args_CXX_STANDARDS}" STREQUAL "") + set(args_CXX_STANDARDS 11) + endif() + + file(READ ${file} file_content) + foreach(cxx_standard ${args_CXX_STANDARDS}) + if(NOT compiler_supports_cpp_${cxx_standard}) + continue() + endif() + + # add unconditionally if C++11 (default) or forced + if(NOT ("${cxx_standard}" STREQUAL 11 OR args_FORCE)) + string(FIND "${file_content}" JSON_HAS_CPP_${cxx_standard} has_cpp_found) + if(${has_cpp_found} EQUAL -1) + continue() + endif() + endif() + + _json_test_add_test(${test_name} ${file} ${args_MAIN} ${cxx_standard}) + endforeach() +endfunction() + +############################################################################# +# json_test_should_build_32bit_test( +# ) +# +# Check if the 32bit unit test should be built based on the value of +# and store the result in the variables and +# . +############################################################################# + +function(json_test_should_build_32bit_test build_32bit_var build_32bit_only_var input) + set(${build_32bit_only_var} OFF PARENT_SCOPE) + string(TOUPPER "${input}" ${build_32bit_var}) + if("${${build_32bit_var}}" STREQUAL AUTO) + # check if compiler is targeting 32bit by default + include(CheckTypeSize) + check_type_size("size_t" sizeof_size_t LANGUAGE CXX) + if(${sizeof_size_t} AND ${sizeof_size_t} EQUAL 4) + message(STATUS "Auto-enabling 32bit unit test.") + set(${build_32bit_var} ON) + else() + set(${build_32bit_var} OFF) + endif() + elseif("${${build_32bit_var}}" STREQUAL ONLY) + set(${build_32bit_only_var} ON PARENT_SCOPE) + endif() + + set(${build_32bit_var} "${${build_32bit_var}}" PARENT_SCOPE) +endfunction() diff --git a/json-develop/docs/Makefile b/json-develop/docs/Makefile new file mode 100644 index 0000000..35c30da --- /dev/null +++ b/json-develop/docs/Makefile @@ -0,0 +1,45 @@ +SRCDIR = ../single_include + +all: create_output + +########################################################################## +# example files +########################################################################## + +# where are the example cpp files +EXAMPLES = $(wildcard examples/*.cpp) + +cxx_standard = $(lastword c++11 $(filter c++%, $(subst ., ,$1))) + +# create output from a stand-alone example file +%.output: %.cpp + @echo "standard $(call cxx_standard $(<:.cpp=))" + $(MAKE) $(<:.cpp=) \ + CPPFLAGS="-I $(SRCDIR) -DJSON_USE_GLOBAL_UDLS=0" \ + CXXFLAGS="-std=$(call cxx_standard,$(<:.cpp=)) -Wno-deprecated-declarations" + ./$(<:.cpp=) > $@ + rm $(<:.cpp=) + +# compare created output with current output of the example files +%.test: %.cpp + $(MAKE) $(<:.cpp=) \ + CPPFLAGS="-I $(SRCDIR) -DJSON_USE_GLOBAL_UDLS=0" \ + CXXFLAGS="-std=$(call cxx_standard,$(<:.cpp=)) -Wno-deprecated-declarations" + ./$(<:.cpp=) > $@ + diff $@ $(<:.cpp=.output) + rm $(<:.cpp=) $@ + +# create output from all stand-alone example files +create_output: $(EXAMPLES:.cpp=.output) + +# check output of all stand-alone example files +check_output: $(EXAMPLES:.cpp=.test) + +# check output of all stand-alone example files (exclude files with platform-dependent output.) +# This target is used in the CI (ci_test_documentation). +check_output_portable: $(filter-out examples/meta.test examples/max_size.test examples/std_hash.test examples/basic_json__CompatibleType.test,$(EXAMPLES:.cpp=.test)) + +clean: + rm -fr $(EXAMPLES:.cpp=) + $(MAKE) clean -C docset + $(MAKE) clean -C mkdocs diff --git a/json-develop/docs/README.md b/json-develop/docs/README.md new file mode 100644 index 0000000..b39d54e --- /dev/null +++ b/json-develop/docs/README.md @@ -0,0 +1,20 @@ +# Documentation + +## Generate documentation + +Note on documentation: The source files contain links to the online documentation at https://json.nlohmann.me. This URL +contains the most recent documentation and should also be applicable to previous versions; documentation for deprecated +functions is not removed, but marked deprecated. + +If you want to see the documentation for a specific tag or commit hash, you can generate it as follows (here for tag +`v3.10.2`): + +```shell +git clone https://github.com/nlohmann/json.git +cd json +git checkout v3.10.2 +make install_venv serve -C docs/mkdocs +``` + +Open URL in your browser. Replace from any URL from the source code `https://json.nlohmann.me` +with `http://127.0.0.1:8000` to see the documentation for your tag or commit hash. diff --git a/json-develop/docs/avatars.png b/json-develop/docs/avatars.png new file mode 100644 index 0000000..0a25221 Binary files /dev/null and b/json-develop/docs/avatars.png differ diff --git a/json-develop/docs/docset/Info.plist b/json-develop/docs/docset/Info.plist new file mode 100644 index 0000000..772ec08 --- /dev/null +++ b/json-develop/docs/docset/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleIdentifier + nlohmann_json + CFBundleName + JSON for Modern C++ + DocSetPlatformFamily + json + isDashDocset + + dashIndexFilePath + index.html + DashDocSetFallbackURL + https://nlohmann.github.io/json/ + isJavaScriptEnabled + + + diff --git a/json-develop/docs/docset/Makefile b/json-develop/docs/docset/Makefile new file mode 100644 index 0000000..eb1cfd3 --- /dev/null +++ b/json-develop/docs/docset/Makefile @@ -0,0 +1,87 @@ +SHELL=/usr/bin/env bash +SED ?= $(shell which gsed 2>/dev/null || which sed) + +MKDOCS_PAGES=$(shell cd ../mkdocs/docs/ && find * -type f -name '*.md' | sort) + +.PHONY: all +all: JSON_for_Modern_C++.tgz + +docSet.dsidx: docSet.sql + # generate index + sqlite3 docSet.dsidx > "$$(ls JSON_for_Modern_C++.docset/Contents/Resources/Documents/assets/stylesheets/main.*.min.css)" + # fix spacing + echo -e "\n\ndiv.md-sidebar div.md-sidebar--secondary, div.md-main__inner { top: 0; margin-top: 0 }" >> "$$(ls JSON_for_Modern_C++.docset/Contents/Resources/Documents/assets/stylesheets/main.*.min.css)" + # remove "JSON for Modern C++" from page titles (fallback) + find JSON_for_Modern_C++.docset/Contents/Resources/Documents -type f -exec $(SED) -i 's| - JSON for Modern C++||' {} + + # replace page titles with name from index, if available + for page in $(MKDOCS_PAGES); do \ + case "$$page" in \ + */index.md) path=$${page/\/index.md/} ;; \ + *) path=$${page/.md/} ;; \ + esac; \ + title=$$(sqlite3 docSet.dsidx "SELECT name FROM searchIndex WHERE path='$$path/index.html'" | tr '\n' ',' | $(SED) -e 's/,/, /g' -e 's/, $$/\n/'); \ + if [ "x$$title" != "x" ]; then \ + $(SED) -i "s%.*%$$title%" "JSON_for_Modern_C++.docset/Contents/Resources/Documents/$$path/index.html"; \ + fi \ + done + # clean up + rm JSON_for_Modern_C++.docset/Contents/Resources/Documents/sitemap.* + # copy index + cp docSet.dsidx JSON_for_Modern_C++.docset/Contents/Resources/ + +JSON_for_Modern_C++.tgz: JSON_for_Modern_C++.docset + tar --exclude='.DS_Store' -cvzf JSON_for_Modern_C++.tgz JSON_for_Modern_C++.docset + +# install docset for Zeal documentation browser (https://zealdocs.org/) +.PHONY: install_docset_zeal +install_docset_zeal: JSON_for_Modern_C++.docset + docset_root=$${XDG_DATA_HOME:-$$HOME/.local/share}/Zeal/Zeal/docsets; \ + rm -rf $$docset_root/JSON_for_Modern_C++.docset; \ + mkdir -p $$docset_root; \ + cp -r JSON_for_Modern_C++.docset $$docset_root/ + +# list mkdocs pages missing from the docset index +.PHONY: list_missing_pages +list_missing_pages: docSet.dsidx + @for page in $(MKDOCS_PAGES); do \ + case "$$page" in \ + */index.md) path=$${page/\/index.md/} ;; \ + *) path=$${page/.md/} ;; \ + esac; \ + if [ "x$$page" != "xindex.md" -a "x$$(sqlite3 docSet.dsidx "SELECT COUNT(*) FROM searchIndex WHERE path='$$path/index.html'")" = "x0" ]; then \ + echo $$page; \ + fi \ + done + +# list paths in the docset index without a corresponding mkdocs page +.PHONY: list_removed_paths +list_removed_paths: docSet.dsidx + @for path in $$(sqlite3 docSet.dsidx "SELECT path FROM searchIndex"); do \ + page=$${path/\/index.html/.md}; \ + page_index=$${path/index.html/index.md}; \ + page_found=0; \ + for p in $(MKDOCS_PAGES); do \ + if [ "x$$p" = "x$$page" -o "x$$p" = "x$$page_index" ]; then \ + page_found=1; \ + fi \ + done; \ + if [ "x$$page_found" = "x0" ]; then \ + echo $$path; \ + fi \ + done + +.PHONY: clean +clean: + rm -f docSet.dsidx + rm -fr JSON_for_Modern_C++.docset JSON_for_Modern_C++.tgz diff --git a/json-develop/docs/docset/README.md b/json-develop/docs/docset/README.md new file mode 100644 index 0000000..79a778e --- /dev/null +++ b/json-develop/docs/docset/README.md @@ -0,0 +1,19 @@ +# docset + +The folder contains the required files to create a [docset](https://kapeli.com/docsets) which can be used in +documentation browsers like [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), or +[Zeal](https://zealdocs.org). + +The docset can be created with + +```sh +make nlohmann_json.docset +``` + +The generated folder `nlohmann_json.docset` can then be opened in the documentation browser. + +A recent version is also part of the [Dash user contributions](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B). + +## Licenses + +The [JSON logo](https://commons.wikimedia.org/wiki/File:JSON_vector_logo.svg) is public domain. diff --git a/json-develop/docs/docset/docSet.sql b/json-develop/docs/docset/docSet.sql new file mode 100644 index 0000000..ea6b4f2 --- /dev/null +++ b/json-develop/docs/docset/docSet.sql @@ -0,0 +1,234 @@ +DROP TABLE IF EXISTS searchIndex; +CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT); +CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path); + +-- API +INSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer', 'Class', 'api/adl_serializer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer::from_json', 'Function', 'api/adl_serializer/from_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer::to_json', 'Function', 'api/adl_serializer/to_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype', 'Class', 'api/byte_container_with_subtype/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::byte_container_with_subtype', 'Constructor', 'api/byte_container_with_subtype/byte_container_with_subtype/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::clear_subtype', 'Method', 'api/byte_container_with_subtype/clear_subtype/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::has_subtype', 'Method', 'api/byte_container_with_subtype/has_subtype/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::set_subtype', 'Method', 'api/byte_container_with_subtype/set_subtype/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::subtype', 'Method', 'api/byte_container_with_subtype/subtype/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json', 'Class', 'api/basic_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::accept', 'Function', 'api/basic_json/accept/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::array', 'Function', 'api/basic_json/array/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::array_t', 'Type', 'api/basic_json/array_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::at', 'Method', 'api/basic_json/at/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::back', 'Method', 'api/basic_json/back/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::basic_json', 'Constructor', 'api/basic_json/basic_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::begin', 'Method', 'api/basic_json/begin/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::binary', 'Function', 'api/basic_json/binary/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::binary_t', 'Type', 'api/basic_json/binary_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::boolean_t', 'Type', 'api/basic_json/boolean_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::cbegin', 'Method', 'api/basic_json/cbegin/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::cbor_tag_handler_t', 'Enum', 'api/basic_json/cbor_tag_handler_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::cend', 'Method', 'api/basic_json/cend/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::clear', 'Method', 'api/basic_json/clear/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::contains', 'Method', 'api/basic_json/contains/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::count', 'Method', 'api/basic_json/count/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::crbegin', 'Method', 'api/basic_json/crbegin/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::crend', 'Method', 'api/basic_json/crend/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::default_object_comparator_t', 'Type', 'api/basic_json/default_object_comparator_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::diff', 'Function', 'api/basic_json/diff/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::dump', 'Method', 'api/basic_json/dump/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::emplace', 'Method', 'api/basic_json/emplace/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::emplace_back', 'Method', 'api/basic_json/emplace_back/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::empty', 'Method', 'api/basic_json/empty/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::end', 'Method', 'api/basic_json/end/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::erase', 'Method', 'api/basic_json/erase/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::error_handler_t', 'Enum', 'api/basic_json/error_handler_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::exception', 'Class', 'api/basic_json/exception/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::find', 'Method', 'api/basic_json/find/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::flatten', 'Method', 'api/basic_json/flatten/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_bjdata', 'Function', 'api/basic_json/from_bjdata/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_bson', 'Function', 'api/basic_json/from_bson/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_cbor', 'Function', 'api/basic_json/from_cbor/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_msgpack', 'Function', 'api/basic_json/from_msgpack/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_ubjson', 'Function', 'api/basic_json/from_ubjson/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::front', 'Method', 'api/basic_json/front/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get', 'Method', 'api/basic_json/get/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_allocator', 'Function', 'api/basic_json/get_allocator/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_binary', 'Method', 'api/basic_json/get_binary/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_ptr', 'Method', 'api/basic_json/get_ptr/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_ref', 'Method', 'api/basic_json/get_ref/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_to', 'Method', 'api/basic_json/get_to/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::input_format_t', 'Enum', 'api/basic_json/input_format_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::insert', 'Method', 'api/basic_json/insert/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::invalid_iterator', 'Class', 'api/basic_json/invalid_iterator/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_array', 'Method', 'api/basic_json/is_array/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_binary', 'Method', 'api/basic_json/is_binary/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_boolean', 'Method', 'api/basic_json/is_boolean/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_discarded', 'Method', 'api/basic_json/is_discarded/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_null', 'Method', 'api/basic_json/is_null/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number', 'Method', 'api/basic_json/is_number/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number_float', 'Method', 'api/basic_json/is_number_float/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number_integer', 'Method', 'api/basic_json/is_number_integer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number_unsigned', 'Method', 'api/basic_json/is_number_unsigned/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_object', 'Method', 'api/basic_json/is_object/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_primitive', 'Method', 'api/basic_json/is_primitive/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_string', 'Method', 'api/basic_json/is_string/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_structured', 'Method', 'api/basic_json/is_structured/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::items', 'Method', 'api/basic_json/items/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::json_serializer', 'Class', 'api/basic_json/json_serializer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::max_size', 'Method', 'api/basic_json/max_size/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::merge_patch', 'Method', 'api/basic_json/merge_patch/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::meta', 'Function', 'api/basic_json/meta/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::number_float_t', 'Type', 'api/basic_json/number_float_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::number_integer_t', 'Type', 'api/basic_json/number_integer_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::number_unsigned_t', 'Type', 'api/basic_json/number_unsigned_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::object', 'Function', 'api/basic_json/object/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::object_comparator_t', 'Type', 'api/basic_json/object_comparator_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::object_t', 'Type', 'api/basic_json/object_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator ValueType', 'Operator', 'api/basic_json/operator_ValueType/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator value_t', 'Operator', 'api/basic_json/operator_value_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator[]', 'Operator', 'api/basic_json/operator[]/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator=', 'Operator', 'api/basic_json/operator=/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator+=', 'Operator', 'api/basic_json/operator+=/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator==', 'Operator', 'api/basic_json/operator_eq/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator!=', 'Operator', 'api/basic_json/operator_ne/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator<', 'Operator', 'api/basic_json/operator_lt/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator<=', 'Operator', 'api/basic_json/operator_le/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator>', 'Operator', 'api/basic_json/operator_gt/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator>=', 'Operator', 'api/basic_json/operator_ge/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator<=>', 'Operator', 'api/basic_json/operator_spaceship/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::out_of_range', 'Class', 'api/basic_json/out_of_range/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::other_error', 'Class', 'api/basic_json/other_error/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parse', 'Function', 'api/basic_json/parse/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parse_error', 'Class', 'api/basic_json/parse_error/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parse_event_t', 'Enum', 'api/basic_json/parse_event_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parser_callback_t', 'Type', 'api/basic_json/parser_callback_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::patch', 'Method', 'api/basic_json/patch/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::patch_inplace', 'Method', 'api/basic_json/patch_inplace/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::push_back', 'Method', 'api/basic_json/push_back/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::rbegin', 'Method', 'api/basic_json/rbegin/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::rend', 'Method', 'api/basic_json/rend/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::sax_parse', 'Function', 'api/basic_json/sax_parse/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::size', 'Method', 'api/basic_json/size/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::string_t', 'Type', 'api/basic_json/string_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::swap', 'Method', 'api/basic_json/swap/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::type', 'Method', 'api/basic_json/type/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::type_error', 'Class', 'api/basic_json/type_error/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::type_name', 'Method', 'api/basic_json/type_name/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::unflatten', 'Method', 'api/basic_json/unflatten/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::update', 'Method', 'api/basic_json/update/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_bjdata', 'Function', 'api/basic_json/to_bjdata/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_bson', 'Function', 'api/basic_json/to_bson/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_cbor', 'Function', 'api/basic_json/to_cbor/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_msgpack', 'Function', 'api/basic_json/to_msgpack/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_string', 'Method', 'api/basic_json/to_string/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_ubjson', 'Function', 'api/basic_json/to_ubjson/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value', 'Method', 'api/basic_json/value/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value_t', 'Enum', 'api/basic_json/value_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::~basic_json', 'Method', 'api/basic_json/~basic_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer', 'Class', 'api/json_pointer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::back', 'Method', 'api/json_pointer/back/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::empty', 'Method', 'api/json_pointer/empty/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::json_pointer', 'Constructor', 'api/json_pointer/json_pointer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator==', 'Operator', 'api/json_pointer/operator_eq/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator!=', 'Operator', 'api/json_pointer/operator_ne/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator/', 'Operator', 'api/json_pointer/operator_slash/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator/=', 'Operator', 'api/json_pointer/operator_slasheq/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator string_t', 'Operator', 'api/json_pointer/operator_string_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::parent_pointer', 'Method', 'api/json_pointer/parent_pointer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::pop_back', 'Method', 'api/json_pointer/pop_back/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::push_back', 'Method', 'api/json_pointer/push_back/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::string_t', 'Type', 'api/json_pointer/string_t/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::to_string', 'Method', 'api/json_pointer/to_string/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax', 'Class', 'api/json_sax/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::binary', 'Method', 'api/json_sax/binary/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::boolean', 'Method', 'api/json_sax/boolean/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::end_array', 'Method', 'api/json_sax/end_array/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::end_object', 'Method', 'api/json_sax/end_object/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::key', 'Method', 'api/json_sax/key/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::null', 'Method', 'api/json_sax/null/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::number_float', 'Method', 'api/json_sax/number_float/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::number_integer', 'Method', 'api/json_sax/number_integer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::number_unsigned', 'Method', 'api/json_sax/number_unsigned/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::parse_error', 'Method', 'api/json_sax/parse_error/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::start_array', 'Method', 'api/json_sax/start_array/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::start_object', 'Method', 'api/json_sax/start_object/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::string', 'Method', 'api/json_sax/string/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('operator""_json', 'Literal', 'api/operator_literal_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('operator""_json_pointer', 'Literal', 'api/operator_literal_json_pointer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('operator<<', 'Operator', 'api/operator_ltlt/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('operator>>', 'Operator', 'api/operator_gtgt/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'api/ordered_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'api/ordered_map/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('std::hash', 'Class', 'api/basic_json/std_hash/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('std::swap', 'Function', 'api/basic_json/std_swap/index.html'); + +-- Features +INSERT INTO searchIndex(name, type, path) VALUES ('Arbitrary Type Conversions', 'Guide', 'features/arbitrary_types/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats', 'Guide', 'features/binary_formats/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: BJData', 'Guide', 'features/binary_formats/bjdata/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: BSON', 'Guide', 'features/binary_formats/bson/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: CBOR', 'Guide', 'features/binary_formats/cbor/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: MessagePack', 'Guide', 'features/binary_formats/messagepack/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: UBJSON', 'Guide', 'features/binary_formats/ubjson/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Binary Values', 'Guide', 'features/binary_values/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Comments', 'Guide', 'features/comments/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Element Access', 'Guide', 'features/element_access/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Access with default value: value', 'Guide', 'features/element_access/default_value/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Checked access: at', 'Guide', 'features/element_access/checked_access/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Unchecked access: operator[]', 'Guide', 'features/element_access/unchecked_access/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Migration Guide', 'Guide', 'integration/migration_guide/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Integration: CMake', 'Guide', 'integration/cmake/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Header only', 'Guide', 'integration/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Package Managers', 'Guide', 'integration/package_managers/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Pkg-config', 'Guide', 'integration/pkg-config/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'features/iterators/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON Merge Patch', 'Guide', 'features/merge_patch/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON Patch and Diff', 'Guide', 'features/json_patch/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON Pointer', 'Guide', 'features/json_pointer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('nlohmann Namespace', 'Guide', 'features/namespace/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Types', 'Guide', 'features/types/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Types: Number Handling', 'Guide', 'features/types/number_handling/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Object Order', 'Guide', 'features/object_order/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Parsing', 'Guide', 'features/parsing/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: JSON Lines', 'Guide', 'features/parsing/json_lines/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: Parser Callbacks', 'Guide', 'features/parsing/parser_callbacks/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: Parsing and Exceptions', 'Guide', 'features/parsing/parse_exceptions/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: SAX Interface', 'Guide', 'features/parsing/sax_interface/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Runtime Assertions', 'Guide', 'features/assertions/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Specializing enum conversion', 'Guide', 'features/enum_conversion/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', 'features/macros/index.html'); + +-- Macros +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'api/macros/json_assert/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'api/macros/json_throw_user/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'api/macros/json_diagnostics/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'api/macros/json_disable_enum_serialization/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_11', 'Macro', 'api/macros/json_has_cpp_11/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_14', 'Macro', 'api/macros/json_has_cpp_11/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_17', 'Macro', 'api/macros/json_has_cpp_11/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_20', 'Macro', 'api/macros/json_has_cpp_11/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_EXPERIMENTAL_FILESYSTEM', 'Macro', 'api/macros/json_has_filesystem/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_FILESYSTEM', 'Macro', 'api/macros/json_has_filesystem/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_RANGES', 'Macro', 'api/macros/json_has_ranges/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_THREE_WAY_COMPARISON', 'Macro', 'api/macros/json_has_three_way_comparison/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_NOEXCEPTION', 'Macro', 'api/macros/json_noexception/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_NO_IO', 'Macro', 'api/macros/json_no_io/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_SKIP_LIBRARY_VERSION_CHECK', 'Macro', 'api/macros/json_skip_library_version_check/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_SKIP_UNSUPPORTED_COMPILER_CHECK', 'Macro', 'api/macros/json_skip_unsupported_compiler_check/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_THROW_USER', 'Macro', 'api/macros/json_throw_user/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'api/macros/json_throw_user/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_GLOBAL_UDLS', 'Macro', 'api/macros/json_use_global_udls/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'api/macros/json_use_implicit_conversions/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON', 'Macro', 'api/macros/json_use_legacy_discarded_value_comparison/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Macros', 'Macro', 'api/macros/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_type_intrusive/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT', 'Macro', 'api/macros/nlohmann_define_type_intrusive/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_type_non_intrusive/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT', 'Macro', 'api/macros/nlohmann_define_type_non_intrusive/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE', 'Macro', 'api/macros/nlohmann_json_namespace/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_BEGIN', 'Macro', 'api/macros/nlohmann_json_namespace_begin/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_END', 'Macro', 'api/macros/nlohmann_json_namespace_begin/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_NO_VERSION', 'Macro', 'api/macros/nlohmann_json_namespace_no_version/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM', 'Macro', 'api/macros/nlohmann_json_serialize_enum/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MAJOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MINOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_PATCH', 'Macro', 'api/macros/nlohmann_json_version_major/index.html'); diff --git a/json-develop/docs/docset/docset.json b/json-develop/docs/docset/docset.json new file mode 100644 index 0000000..a11cead --- /dev/null +++ b/json-develop/docs/docset/docset.json @@ -0,0 +1,10 @@ +{ + "name": "JSON for Modern C++", + "version": "3.11.2", + "archive": "JSON_for_Modern_C++.tgz", + "author": { + "name": "Niels Lohmann", + "link": "https://twitter.com/nlohmann" + }, + "aliases": ["nlohmann/json"] +} diff --git a/json-develop/docs/docset/icon.png b/json-develop/docs/docset/icon.png new file mode 100644 index 0000000..7197d0a Binary files /dev/null and b/json-develop/docs/docset/icon.png differ diff --git a/json-develop/docs/docset/icon@2x.png b/json-develop/docs/docset/icon@2x.png new file mode 100644 index 0000000..5f2fac8 Binary files /dev/null and b/json-develop/docs/docset/icon@2x.png differ diff --git a/json-develop/docs/examples/README.cpp b/json-develop/docs/examples/README.cpp new file mode 100644 index 0000000..2d641e5 --- /dev/null +++ b/json-develop/docs/examples/README.cpp @@ -0,0 +1,39 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j = + { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + { + "answer", { + {"everything", 42} + } + }, + {"list", {1, 0, 2}}, + { + "object", { + {"currency", "USD"}, + {"value", 42.99} + } + } + }; + + // add new values + j["new"]["key"]["value"] = {"another", "list"}; + + // count elements + auto s = j.size(); + j["size"] = s; + + // pretty print with indent of 4 spaces + std::cout << std::setw(4) << j << '\n'; +} diff --git a/json-develop/docs/examples/README.output b/json-develop/docs/examples/README.output new file mode 100644 index 0000000..31188d4 --- /dev/null +++ b/json-develop/docs/examples/README.output @@ -0,0 +1,27 @@ +{ + "answer": { + "everything": 42 + }, + "happy": true, + "list": [ + 1, + 0, + 2 + ], + "name": "Niels", + "new": { + "key": { + "value": [ + "another", + "list" + ] + } + }, + "nothing": null, + "object": { + "currency": "USD", + "value": 42.99 + }, + "pi": 3.141, + "size": 8 +} diff --git a/json-develop/docs/examples/accept__string.cpp b/json-develop/docs/examples/accept__string.cpp new file mode 100644 index 0000000..8eb3d9b --- /dev/null +++ b/json-develop/docs/examples/accept__string.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a valid JSON text + auto valid_text = R"( + { + "numbers": [1, 2, 3] + } + )"; + + // an invalid JSON text + auto invalid_text = R"( + { + "strings": ["extra", "comma", ] + } + )"; + + std::cout << std::boolalpha + << json::accept(valid_text) << ' ' + << json::accept(invalid_text) << '\n'; +} diff --git a/json-develop/docs/examples/accept__string.output b/json-develop/docs/examples/accept__string.output new file mode 100644 index 0000000..836a593 --- /dev/null +++ b/json-develop/docs/examples/accept__string.output @@ -0,0 +1 @@ +true false diff --git a/json-develop/docs/examples/array.cpp b/json-develop/docs/examples/array.cpp new file mode 100644 index 0000000..139b5ef --- /dev/null +++ b/json-develop/docs/examples/array.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON arrays + json j_no_init_list = json::array(); + json j_empty_init_list = json::array({}); + json j_nonempty_init_list = json::array({1, 2, 3, 4}); + json j_list_of_pairs = json::array({ {"one", 1}, {"two", 2} }); + + // serialize the JSON arrays + std::cout << j_no_init_list << '\n'; + std::cout << j_empty_init_list << '\n'; + std::cout << j_nonempty_init_list << '\n'; + std::cout << j_list_of_pairs << '\n'; +} diff --git a/json-develop/docs/examples/array.output b/json-develop/docs/examples/array.output new file mode 100644 index 0000000..4e75a1b --- /dev/null +++ b/json-develop/docs/examples/array.output @@ -0,0 +1,4 @@ +[] +[] +[1,2,3,4] +[["one",1],["two",2]] diff --git a/json-develop/docs/examples/array_t.cpp b/json-develop/docs/examples/array_t.cpp new file mode 100644 index 0000000..0964857 --- /dev/null +++ b/json-develop/docs/examples/array_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same, json::array_t>::value << std::endl; +} diff --git a/json-develop/docs/examples/array_t.output b/json-develop/docs/examples/array_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/array_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/at__json_pointer.cpp b/json-develop/docs/examples/at__json_pointer.cpp new file mode 100644 index 0000000..26dfd8e --- /dev/null +++ b/json-develop/docs/examples/at__json_pointer.cpp @@ -0,0 +1,104 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j.at("/number"_json_pointer) << '\n'; + // output element with JSON pointer "/string" + std::cout << j.at("/string"_json_pointer) << '\n'; + // output element with JSON pointer "/array" + std::cout << j.at("/array"_json_pointer) << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j.at("/array/1"_json_pointer) << '\n'; + + // writing access + + // change the string + j.at("/string"_json_pointer) = "bar"; + // output the changed string + std::cout << j["string"] << '\n'; + + // change an array element + j.at("/array/1"_json_pointer) = 21; + // output the changed array + std::cout << j["array"] << '\n'; + + + // out_of_range.106 + try + { + // try to use an array index with leading '0' + json::reference ref = j.at("/array/01"_json_pointer); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.109 + try + { + // try to use an array index that is not a number + json::reference ref = j.at("/array/one"_json_pointer); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.401 + try + { + // try to use an invalid array index + json::reference ref = j.at("/array/4"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.402 + try + { + // try to use the array index '-' + json::reference ref = j.at("/array/-"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.403 + try + { + // try to use a JSON pointer to a nonexistent object key + json::const_reference ref = j.at("/foo"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.404 + try + { + // try to use a JSON pointer that cannot be resolved + json::reference ref = j.at("/number/foo"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/at__json_pointer.output b/json-develop/docs/examples/at__json_pointer.output new file mode 100644 index 0000000..1d29893 --- /dev/null +++ b/json-develop/docs/examples/at__json_pointer.output @@ -0,0 +1,12 @@ +1 +"foo" +[1,2] +2 +"bar" +[1,21] +[json.exception.parse_error.106] parse error: array index '01' must not begin with '0' +[json.exception.parse_error.109] parse error: array index 'one' is not a number +[json.exception.out_of_range.401] array index 4 is out of range +[json.exception.out_of_range.402] array index '-' (2) is out of range +[json.exception.out_of_range.403] key 'foo' not found +[json.exception.out_of_range.404] unresolved reference token 'foo' diff --git a/json-develop/docs/examples/at__json_pointer_const.cpp b/json-develop/docs/examples/at__json_pointer_const.cpp new file mode 100644 index 0000000..f049bd8 --- /dev/null +++ b/json-develop/docs/examples/at__json_pointer_const.cpp @@ -0,0 +1,80 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + const json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j.at("/number"_json_pointer) << '\n'; + // output element with JSON pointer "/string" + std::cout << j.at("/string"_json_pointer) << '\n'; + // output element with JSON pointer "/array" + std::cout << j.at("/array"_json_pointer) << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j.at("/array/1"_json_pointer) << '\n'; + + // out_of_range.109 + try + { + // try to use an array index that is not a number + json::const_reference ref = j.at("/array/one"_json_pointer); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.401 + try + { + // try to use an invalid array index + json::const_reference ref = j.at("/array/4"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.402 + try + { + // try to use the array index '-' + json::const_reference ref = j.at("/array/-"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.403 + try + { + // try to use a JSON pointer to a nonexistent object key + json::const_reference ref = j.at("/foo"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.404 + try + { + // try to use a JSON pointer that cannot be resolved + json::const_reference ref = j.at("/number/foo"_json_pointer); + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/at__json_pointer_const.output b/json-develop/docs/examples/at__json_pointer_const.output new file mode 100644 index 0000000..aaf8f18 --- /dev/null +++ b/json-develop/docs/examples/at__json_pointer_const.output @@ -0,0 +1,9 @@ +1 +"foo" +[1,2] +2 +[json.exception.parse_error.109] parse error: array index 'one' is not a number +[json.exception.out_of_range.401] array index 4 is out of range +[json.exception.out_of_range.402] array index '-' (2) is out of range +[json.exception.out_of_range.403] key 'foo' not found +[json.exception.out_of_range.404] unresolved reference token 'foo' diff --git a/json-develop/docs/examples/at__keytype.c++17.cpp b/json-develop/docs/examples/at__keytype.c++17.cpp new file mode 100644 index 0000000..3491cb9 --- /dev/null +++ b/json-develop/docs/examples/at__keytype.c++17.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create JSON object + json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" using string_view + std::cout << object.at("the ugly"sv) << '\n'; + + // change element with key "the bad" using string_view + object.at("the bad"sv) = "il cattivo"; + + // output changed array + std::cout << object << '\n'; + + + // exception type_error.304 + try + { + // use at() with string_view on a non-object type + json str = "I am a string"; + str.at("the good"sv) = "Another string"; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to write at a nonexisting key using string_view + object.at("the fast"sv) = "il rapido"; + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/at__keytype.c++17.output b/json-develop/docs/examples/at__keytype.c++17.output new file mode 100644 index 0000000..b544b72 --- /dev/null +++ b/json-develop/docs/examples/at__keytype.c++17.output @@ -0,0 +1,4 @@ +"il brutto" +{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"} +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.403] key 'the fast' not found diff --git a/json-develop/docs/examples/at__keytype_const.c++17.cpp b/json-develop/docs/examples/at__keytype_const.c++17.cpp new file mode 100644 index 0000000..ec93c70 --- /dev/null +++ b/json-develop/docs/examples/at__keytype_const.c++17.cpp @@ -0,0 +1,44 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create JSON object + const json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" using string_view + std::cout << object.at("the ugly"sv) << '\n'; + + + // exception type_error.304 + try + { + // use at() with string_view on a non-object type + const json str = "I am a string"; + std::cout << str.at("the good"sv) << '\n'; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to read from a nonexisting key using string_view + std::cout << object.at("the fast"sv) << '\n'; + } + catch (json::out_of_range) + { + std::cout << "out of range" << '\n'; + } +} diff --git a/json-develop/docs/examples/at__keytype_const.c++17.output b/json-develop/docs/examples/at__keytype_const.c++17.output new file mode 100644 index 0000000..40ca3f0 --- /dev/null +++ b/json-develop/docs/examples/at__keytype_const.c++17.output @@ -0,0 +1,3 @@ +"il brutto" +[json.exception.type_error.304] cannot use at() with string +out of range diff --git a/json-develop/docs/examples/at__object_t_key_type.cpp b/json-develop/docs/examples/at__object_t_key_type.cpp new file mode 100644 index 0000000..202f8a2 --- /dev/null +++ b/json-develop/docs/examples/at__object_t_key_type.cpp @@ -0,0 +1,48 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON object + json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" + std::cout << object.at("the ugly") << '\n'; + + // change element with key "the bad" + object.at("the bad") = "il cattivo"; + + // output changed array + std::cout << object << '\n'; + + + // exception type_error.304 + try + { + // use at() on a non-object type + json str = "I am a string"; + str.at("the good") = "Another string"; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to write at a nonexisting key + object.at("the fast") = "il rapido"; + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/at__object_t_key_type.output b/json-develop/docs/examples/at__object_t_key_type.output new file mode 100644 index 0000000..b544b72 --- /dev/null +++ b/json-develop/docs/examples/at__object_t_key_type.output @@ -0,0 +1,4 @@ +"il brutto" +{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"} +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.403] key 'the fast' not found diff --git a/json-develop/docs/examples/at__object_t_key_type_const.cpp b/json-develop/docs/examples/at__object_t_key_type_const.cpp new file mode 100644 index 0000000..e5244f3 --- /dev/null +++ b/json-develop/docs/examples/at__object_t_key_type_const.cpp @@ -0,0 +1,42 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON object + const json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" + std::cout << object.at("the ugly") << '\n'; + + + // exception type_error.304 + try + { + // use at() on a non-object type + const json str = "I am a string"; + std::cout << str.at("the good") << '\n'; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to read from a nonexisting key + std::cout << object.at("the fast") << '\n'; + } + catch (json::out_of_range) + { + std::cout << "out of range" << '\n'; + } +} diff --git a/json-develop/docs/examples/at__object_t_key_type_const.output b/json-develop/docs/examples/at__object_t_key_type_const.output new file mode 100644 index 0000000..40ca3f0 --- /dev/null +++ b/json-develop/docs/examples/at__object_t_key_type_const.output @@ -0,0 +1,3 @@ +"il brutto" +[json.exception.type_error.304] cannot use at() with string +out of range diff --git a/json-develop/docs/examples/at__size_type.cpp b/json-develop/docs/examples/at__size_type.cpp new file mode 100644 index 0000000..65baedd --- /dev/null +++ b/json-develop/docs/examples/at__size_type.cpp @@ -0,0 +1,43 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON array + json array = {"first", "2nd", "third", "fourth"}; + + // output element at index 2 (third element) + std::cout << array.at(2) << '\n'; + + // change element at index 1 (second element) to "second" + array.at(1) = "second"; + + // output changed array + std::cout << array << '\n'; + + + // exception type_error.304 + try + { + // use at() on a non-array type + json str = "I am a string"; + str.at(0) = "Another string"; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to write beyond the array limit + array.at(5) = "sixth"; + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/at__size_type.output b/json-develop/docs/examples/at__size_type.output new file mode 100644 index 0000000..5402643 --- /dev/null +++ b/json-develop/docs/examples/at__size_type.output @@ -0,0 +1,4 @@ +"third" +["first","second","third","fourth"] +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.401] array index 5 is out of range diff --git a/json-develop/docs/examples/at__size_type_const.cpp b/json-develop/docs/examples/at__size_type_const.cpp new file mode 100644 index 0000000..faa4cff --- /dev/null +++ b/json-develop/docs/examples/at__size_type_const.cpp @@ -0,0 +1,37 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON array + const json array = {"first", "2nd", "third", "fourth"}; + + // output element at index 2 (third element) + std::cout << array.at(2) << '\n'; + + + // exception type_error.304 + try + { + // use at() on a non-array type + const json str = "I am a string"; + std::cout << str.at(0) << '\n'; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to read beyond the array limit + std::cout << array.at(5) << '\n'; + } + catch (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/at__size_type_const.output b/json-develop/docs/examples/at__size_type_const.output new file mode 100644 index 0000000..8135a27 --- /dev/null +++ b/json-develop/docs/examples/at__size_type_const.output @@ -0,0 +1,3 @@ +"third" +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.401] array index 5 is out of range diff --git a/json-develop/docs/examples/back.cpp b/json-develop/docs/examples/back.cpp new file mode 100644 index 0000000..1439a82 --- /dev/null +++ b/json-develop/docs/examples/back.cpp @@ -0,0 +1,38 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call back() + std::cout << j_boolean.back() << '\n'; + std::cout << j_number_integer.back() << '\n'; + std::cout << j_number_float.back() << '\n'; + std::cout << j_object.back() << '\n'; + //std::cout << j_object_empty.back() << '\n'; // undefined behavior + std::cout << j_array.back() << '\n'; + //std::cout << j_array_empty.back() << '\n'; // undefined behavior + std::cout << j_string.back() << '\n'; + + // back() called on a null value + try + { + json j_null; + j_null.back(); + } + catch (json::invalid_iterator& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/back.output b/json-develop/docs/examples/back.output new file mode 100644 index 0000000..2990dbf --- /dev/null +++ b/json-develop/docs/examples/back.output @@ -0,0 +1,7 @@ +true +17 +23.42 +2 +16 +"Hello, world" +[json.exception.invalid_iterator.214] cannot get value diff --git a/json-develop/docs/examples/basic_json__CompatibleType.cpp b/json-develop/docs/examples/basic_json__CompatibleType.cpp new file mode 100644 index 0000000..e2f01aa --- /dev/null +++ b/json-develop/docs/examples/basic_json__CompatibleType.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // ============ + // object types + // ============ + + // create an object from an object_t value + json::object_t object_value = { {"one", 1}, {"two", 2} }; + json j_object_t(object_value); + + // create an object from std::map + std::map c_map + { + {"one", 1}, {"two", 2}, {"three", 3} + }; + json j_map(c_map); + + // create an object from std::unordered_map + std::unordered_map c_umap + { + {"one", 1.2}, {"two", 2.3}, {"three", 3.4} + }; + json j_umap(c_umap); + + // create an object from std::multimap + std::multimap c_mmap + { + {"one", true}, {"two", true}, {"three", false}, {"three", true} + }; + json j_mmap(c_mmap); // only one entry for key "three" is used + + // create an object from std::unordered_multimap + std::unordered_multimap c_ummap + { + {"one", true}, {"two", true}, {"three", false}, {"three", true} + }; + json j_ummap(c_ummap); // only one entry for key "three" is used + + // serialize the JSON objects + std::cout << j_object_t << '\n'; + std::cout << j_map << '\n'; + std::cout << j_umap << '\n'; + std::cout << j_mmap << '\n'; + std::cout << j_ummap << "\n\n"; + + + // =========== + // array types + // =========== + + // create an array from an array_t value + json::array_t array_value = {"one", "two", 3, 4.5, false}; + json j_array_t(array_value); + + // create an array from std::vector + std::vector c_vector {1, 2, 3, 4}; + json j_vec(c_vector); + + // create an array from std::valarray + std::valarray c_valarray {10, 9, 8, 7}; + json j_valarray(c_valarray); + + // create an array from std::deque + std::deque c_deque {1.2, 2.3, 3.4, 5.6}; + json j_deque(c_deque); + + // create an array from std::list + std::list c_list {true, true, false, true}; + json j_list(c_list); + + // create an array from std::forward_list + std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; + json j_flist(c_flist); + + // create an array from std::array + std::array c_array {{1, 2, 3, 4}}; + json j_array(c_array); + + // create an array from std::set + std::set c_set {"one", "two", "three", "four", "one"}; + json j_set(c_set); // only one entry for "one" is used + + // create an array from std::unordered_set + std::unordered_set c_uset {"one", "two", "three", "four", "one"}; + json j_uset(c_uset); // only one entry for "one" is used + + // create an array from std::multiset + std::multiset c_mset {"one", "two", "one", "four"}; + json j_mset(c_mset); // both entries for "one" are used + + // create an array from std::unordered_multiset + std::unordered_multiset c_umset {"one", "two", "one", "four"}; + json j_umset(c_umset); // both entries for "one" are used + + // serialize the JSON arrays + std::cout << j_array_t << '\n'; + std::cout << j_vec << '\n'; + std::cout << j_valarray << '\n'; + std::cout << j_deque << '\n'; + std::cout << j_list << '\n'; + std::cout << j_flist << '\n'; + std::cout << j_array << '\n'; + std::cout << j_set << '\n'; + std::cout << j_uset << '\n'; + std::cout << j_mset << '\n'; + std::cout << j_umset << "\n\n"; + + + // ============ + // string types + // ============ + + // create string from a string_t value + json::string_t string_value = "The quick brown fox jumps over the lazy dog."; + json j_string_t(string_value); + + // create a JSON string directly from a string literal + json j_string_literal("The quick brown fox jumps over the lazy dog."); + + // create string from std::string + std::string s_stdstring = "The quick brown fox jumps over the lazy dog."; + json j_stdstring(s_stdstring); + + // serialize the JSON strings + std::cout << j_string_t << '\n'; + std::cout << j_string_literal << '\n'; + std::cout << j_stdstring << "\n\n"; + + + // ============ + // number types + // ============ + + // create a JSON number from number_integer_t + json::number_integer_t value_integer_t = -42; + json j_integer_t(value_integer_t); + + // create a JSON number from number_unsigned_t + json::number_integer_t value_unsigned_t = 17; + json j_unsigned_t(value_unsigned_t); + + // create a JSON number from an anonymous enum + enum { enum_value = 17 }; + json j_enum(enum_value); + + // create values of different integer types + short n_short = 42; + int n_int = -23; + long n_long = 1024; + int_least32_t n_int_least32_t = -17; + uint8_t n_uint8_t = 8; + + // create (integer) JSON numbers + json j_short(n_short); + json j_int(n_int); + json j_long(n_long); + json j_int_least32_t(n_int_least32_t); + json j_uint8_t(n_uint8_t); + + // create values of different floating-point types + json::number_float_t v_ok = 3.141592653589793; + json::number_float_t v_nan = NAN; + json::number_float_t v_infinity = INFINITY; + + // create values of different floating-point types + float n_float = 42.23; + float n_float_nan = 1.0f / 0.0f; + double n_double = 23.42; + + // create (floating point) JSON numbers + json j_ok(v_ok); + json j_nan(v_nan); + json j_infinity(v_infinity); + json j_float(n_float); + json j_float_nan(n_float_nan); + json j_double(n_double); + + // serialize the JSON numbers + std::cout << j_integer_t << '\n'; + std::cout << j_unsigned_t << '\n'; + std::cout << j_enum << '\n'; + std::cout << j_short << '\n'; + std::cout << j_int << '\n'; + std::cout << j_long << '\n'; + std::cout << j_int_least32_t << '\n'; + std::cout << j_uint8_t << '\n'; + std::cout << j_ok << '\n'; + std::cout << j_nan << '\n'; + std::cout << j_infinity << '\n'; + std::cout << j_float << '\n'; + std::cout << j_float_nan << '\n'; + std::cout << j_double << "\n\n"; + + + // ============= + // boolean types + // ============= + + // create boolean values + json j_truth = true; + json j_falsity = false; + + // serialize the JSON booleans + std::cout << j_truth << '\n'; + std::cout << j_falsity << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__CompatibleType.output b/json-develop/docs/examples/basic_json__CompatibleType.output new file mode 100644 index 0000000..2337e81 --- /dev/null +++ b/json-develop/docs/examples/basic_json__CompatibleType.output @@ -0,0 +1,39 @@ +{"one":1,"two":2} +{"one":1,"three":3,"two":2} +{"one":1.2,"three":3.4,"two":2.3} +{"one":true,"three":false,"two":true} +{"one":true,"three":false,"two":true} + +["one","two",3,4.5,false] +[1,2,3,4] +[10,9,8,7] +[1.2,2.3,3.4,5.6] +[true,true,false,true] +[12345678909876,23456789098765,34567890987654,45678909876543] +[1,2,3,4] +["four","one","three","two"] +["four","three","two","one"] +["four","one","one","two"] +["four","two","one","one"] + +"The quick brown fox jumps over the lazy dog." +"The quick brown fox jumps over the lazy dog." +"The quick brown fox jumps over the lazy dog." + +-42 +17 +17 +42 +-23 +1024 +-17 +8 +3.141592653589793 +null +null +42.22999954223633 +null +23.42 + +true +false diff --git a/json-develop/docs/examples/basic_json__InputIt_InputIt.cpp b/json-develop/docs/examples/basic_json__InputIt_InputIt.cpp new file mode 100644 index 0000000..ed5aff9 --- /dev/null +++ b/json-develop/docs/examples/basic_json__InputIt_InputIt.cpp @@ -0,0 +1,32 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_array = {"alpha", "bravo", "charly", "delta", "easy"}; + json j_number = 42; + json j_object = {{"one", "eins"}, {"two", "zwei"}}; + + // create copies using iterators + json j_array_range(j_array.begin() + 1, j_array.end() - 2); + json j_number_range(j_number.begin(), j_number.end()); + json j_object_range(j_object.begin(), j_object.find("two")); + + // serialize the values + std::cout << j_array_range << '\n'; + std::cout << j_number_range << '\n'; + std::cout << j_object_range << '\n'; + + // example for an exception + try + { + json j_invalid(j_number.begin() + 1, j_number.end()); + } + catch (json::invalid_iterator& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/basic_json__InputIt_InputIt.output b/json-develop/docs/examples/basic_json__InputIt_InputIt.output new file mode 100644 index 0000000..bfb0177 --- /dev/null +++ b/json-develop/docs/examples/basic_json__InputIt_InputIt.output @@ -0,0 +1,4 @@ +["bravo","charly"] +42 +{"one":"eins"} +[json.exception.invalid_iterator.204] iterators out of range diff --git a/json-develop/docs/examples/basic_json__basic_json.cpp b/json-develop/docs/examples/basic_json__basic_json.cpp new file mode 100644 index 0000000..17136f4 --- /dev/null +++ b/json-develop/docs/examples/basic_json__basic_json.cpp @@ -0,0 +1,17 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json j1 = {"one", "two", 3, 4.5, false}; + + // create a copy + json j2(j1); + + // serialize the JSON array + std::cout << j1 << " = " << j2 << '\n'; + std::cout << std::boolalpha << (j1 == j2) << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__basic_json.output b/json-develop/docs/examples/basic_json__basic_json.output new file mode 100644 index 0000000..ee93a41 --- /dev/null +++ b/json-develop/docs/examples/basic_json__basic_json.output @@ -0,0 +1,2 @@ +["one","two",3,4.5,false] = ["one","two",3,4.5,false] +true diff --git a/json-develop/docs/examples/basic_json__copyassignment.cpp b/json-develop/docs/examples/basic_json__copyassignment.cpp new file mode 100644 index 0000000..2d86574 --- /dev/null +++ b/json-develop/docs/examples/basic_json__copyassignment.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json a = 23; + json b = 42; + + // copy-assign a to b + b = a; + + // serialize the JSON arrays + std::cout << a << '\n'; + std::cout << b << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__copyassignment.output b/json-develop/docs/examples/basic_json__copyassignment.output new file mode 100644 index 0000000..c1eee21 --- /dev/null +++ b/json-develop/docs/examples/basic_json__copyassignment.output @@ -0,0 +1,2 @@ +23 +23 diff --git a/json-develop/docs/examples/basic_json__list_init_t.cpp b/json-develop/docs/examples/basic_json__list_init_t.cpp new file mode 100644 index 0000000..78611e1 --- /dev/null +++ b/json-develop/docs/examples/basic_json__list_init_t.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_empty_init_list = json({}); + json j_object = { {"one", 1}, {"two", 2} }; + json j_array = {1, 2, 3, 4}; + json j_nested_object = { {"one", {1}}, {"two", {1, 2}} }; + json j_nested_array = { {{1}, "one"}, {{1, 2}, "two"} }; + + // serialize the JSON value + std::cout << j_empty_init_list << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_nested_object << '\n'; + std::cout << j_nested_array << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__list_init_t.output b/json-develop/docs/examples/basic_json__list_init_t.output new file mode 100644 index 0000000..d38f5b8 --- /dev/null +++ b/json-develop/docs/examples/basic_json__list_init_t.output @@ -0,0 +1,5 @@ +{} +{"one":1,"two":2} +[1,2,3,4] +{"one":[1],"two":[1,2]} +[[[1],"one"],[[1,2],"two"]] diff --git a/json-develop/docs/examples/basic_json__moveconstructor.cpp b/json-develop/docs/examples/basic_json__moveconstructor.cpp new file mode 100644 index 0000000..48b68f6 --- /dev/null +++ b/json-develop/docs/examples/basic_json__moveconstructor.cpp @@ -0,0 +1,17 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json a = 23; + + // move contents of a to b + json b(std::move(a)); + + // serialize the JSON arrays + std::cout << a << '\n'; + std::cout << b << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__moveconstructor.output b/json-develop/docs/examples/basic_json__moveconstructor.output new file mode 100644 index 0000000..911b5b1 --- /dev/null +++ b/json-develop/docs/examples/basic_json__moveconstructor.output @@ -0,0 +1,2 @@ +null +23 diff --git a/json-develop/docs/examples/basic_json__nullptr_t.cpp b/json-develop/docs/examples/basic_json__nullptr_t.cpp new file mode 100644 index 0000000..7a43666 --- /dev/null +++ b/json-develop/docs/examples/basic_json__nullptr_t.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // implicitly create a JSON null value + json j1; + + // explicitly create a JSON null value + json j2(nullptr); + + // serialize the JSON null value + std::cout << j1 << '\n' << j2 << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__nullptr_t.output b/json-develop/docs/examples/basic_json__nullptr_t.output new file mode 100644 index 0000000..c1e4b6c --- /dev/null +++ b/json-develop/docs/examples/basic_json__nullptr_t.output @@ -0,0 +1,2 @@ +null +null diff --git a/json-develop/docs/examples/basic_json__size_type_basic_json.cpp b/json-develop/docs/examples/basic_json__size_type_basic_json.cpp new file mode 100644 index 0000000..9ec7677 --- /dev/null +++ b/json-develop/docs/examples/basic_json__size_type_basic_json.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array by creating copies of a JSON value + json value = "Hello"; + json array_0 = json(0, value); + json array_1 = json(1, value); + json array_5 = json(5, value); + + // serialize the JSON arrays + std::cout << array_0 << '\n'; + std::cout << array_1 << '\n'; + std::cout << array_5 << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__size_type_basic_json.output b/json-develop/docs/examples/basic_json__size_type_basic_json.output new file mode 100644 index 0000000..f4c59b3 --- /dev/null +++ b/json-develop/docs/examples/basic_json__size_type_basic_json.output @@ -0,0 +1,3 @@ +[] +["Hello"] +["Hello","Hello","Hello","Hello","Hello"] diff --git a/json-develop/docs/examples/basic_json__value_t.cpp b/json-develop/docs/examples/basic_json__value_t.cpp new file mode 100644 index 0000000..c306731 --- /dev/null +++ b/json-develop/docs/examples/basic_json__value_t.cpp @@ -0,0 +1,25 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create the different JSON values with default values + json j_null(json::value_t::null); + json j_boolean(json::value_t::boolean); + json j_number_integer(json::value_t::number_integer); + json j_number_float(json::value_t::number_float); + json j_object(json::value_t::object); + json j_array(json::value_t::array); + json j_string(json::value_t::string); + + // serialize the JSON values + std::cout << j_null << '\n'; + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} diff --git a/json-develop/docs/examples/basic_json__value_t.output b/json-develop/docs/examples/basic_json__value_t.output new file mode 100644 index 0000000..ea542ca --- /dev/null +++ b/json-develop/docs/examples/basic_json__value_t.output @@ -0,0 +1,7 @@ +null +false +0 +0.0 +{} +[] +"" diff --git a/json-develop/docs/examples/begin.cpp b/json-develop/docs/examples/begin.cpp new file mode 100644 index 0000000..654835b --- /dev/null +++ b/json-develop/docs/examples/begin.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the first element + json::iterator it = array.begin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/begin.output b/json-develop/docs/examples/begin.output new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/json-develop/docs/examples/begin.output @@ -0,0 +1 @@ +1 diff --git a/json-develop/docs/examples/binary.cpp b/json-develop/docs/examples/binary.cpp new file mode 100644 index 0000000..617ce60 --- /dev/null +++ b/json-develop/docs/examples/binary.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a binary vector + std::vector vec = {0xCA, 0xFE, 0xBA, 0xBE}; + + // create a binary JSON value with subtype 42 + json j = json::binary(vec, 42); + + // output type and subtype + std::cout << "type: " << j.type_name() << ", subtype: " << j.get_binary().subtype() << std::endl; +} diff --git a/json-develop/docs/examples/binary.output b/json-develop/docs/examples/binary.output new file mode 100644 index 0000000..74b05d2 --- /dev/null +++ b/json-develop/docs/examples/binary.output @@ -0,0 +1 @@ +type: binary, subtype: 42 diff --git a/json-develop/docs/examples/binary_t.cpp b/json-develop/docs/examples/binary_t.cpp new file mode 100644 index 0000000..bfaee5c --- /dev/null +++ b/json-develop/docs/examples/binary_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same>, json::binary_t>::value << std::endl; +} diff --git a/json-develop/docs/examples/binary_t.output b/json-develop/docs/examples/binary_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/binary_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/boolean_t.cpp b/json-develop/docs/examples/boolean_t.cpp new file mode 100644 index 0000000..75b8c99 --- /dev/null +++ b/json-develop/docs/examples/boolean_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/json-develop/docs/examples/boolean_t.output b/json-develop/docs/examples/boolean_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/boolean_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/byte_container_with_subtype__byte_container_with_subtype.cpp b/json-develop/docs/examples/byte_container_with_subtype__byte_container_with_subtype.cpp new file mode 100644 index 0000000..1c10be5 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__byte_container_with_subtype.cpp @@ -0,0 +1,23 @@ +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +using json = nlohmann::json; + +int main() +{ + // (1) create empty container + auto c1 = byte_container_with_subtype(); + + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // (2) create container + auto c2 = byte_container_with_subtype(bytes); + + // (3) create container with subtype + auto c3 = byte_container_with_subtype(bytes, 42); + + std::cout << json(c1) << "\n" << json(c2) << "\n" << json(c3) << std::endl; +} diff --git a/json-develop/docs/examples/byte_container_with_subtype__byte_container_with_subtype.output b/json-develop/docs/examples/byte_container_with_subtype__byte_container_with_subtype.output new file mode 100644 index 0000000..67ac1b2 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__byte_container_with_subtype.output @@ -0,0 +1,3 @@ +{"bytes":[],"subtype":null} +{"bytes":[202,254,186,190],"subtype":null} +{"bytes":[202,254,186,190],"subtype":42} diff --git a/json-develop/docs/examples/byte_container_with_subtype__clear_subtype.cpp b/json-develop/docs/examples/byte_container_with_subtype__clear_subtype.cpp new file mode 100644 index 0000000..f9ce684 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__clear_subtype.cpp @@ -0,0 +1,21 @@ +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +using json = nlohmann::json; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container with subtype + auto c1 = byte_container_with_subtype(bytes, 42); + + std::cout << "before calling clear_subtype(): " << json(c1) << '\n'; + + c1.clear_subtype(); + + std::cout << "after calling clear_subtype(): " << json(c1) << '\n'; +} diff --git a/json-develop/docs/examples/byte_container_with_subtype__clear_subtype.output b/json-develop/docs/examples/byte_container_with_subtype__clear_subtype.output new file mode 100644 index 0000000..9d82129 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__clear_subtype.output @@ -0,0 +1,2 @@ +before calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":42} +after calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":null} diff --git a/json-develop/docs/examples/byte_container_with_subtype__has_subtype.cpp b/json-develop/docs/examples/byte_container_with_subtype__has_subtype.cpp new file mode 100644 index 0000000..61c21ea --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__has_subtype.cpp @@ -0,0 +1,19 @@ +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container + auto c1 = byte_container_with_subtype(bytes); + + // create container with subtype + auto c2 = byte_container_with_subtype(bytes, 42); + + std::cout << std::boolalpha << "c1.has_subtype() = " << c1.has_subtype() + << "\nc2.has_subtype() = " << c2.has_subtype() << std::endl; +} diff --git a/json-develop/docs/examples/byte_container_with_subtype__has_subtype.output b/json-develop/docs/examples/byte_container_with_subtype__has_subtype.output new file mode 100644 index 0000000..f4aade2 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__has_subtype.output @@ -0,0 +1,2 @@ +c1.has_subtype() = false +c2.has_subtype() = true diff --git a/json-develop/docs/examples/byte_container_with_subtype__set_subtype.cpp b/json-develop/docs/examples/byte_container_with_subtype__set_subtype.cpp new file mode 100644 index 0000000..b2694c5 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__set_subtype.cpp @@ -0,0 +1,22 @@ +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +using json = nlohmann::json; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container without subtype + auto c = byte_container_with_subtype(bytes); + + std::cout << "before calling set_subtype(42): " << json(c) << '\n'; + + // set the subtype + c.set_subtype(42); + + std::cout << "after calling set_subtype(42): " << json(c) << '\n'; +} diff --git a/json-develop/docs/examples/byte_container_with_subtype__set_subtype.output b/json-develop/docs/examples/byte_container_with_subtype__set_subtype.output new file mode 100644 index 0000000..648b3ef --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__set_subtype.output @@ -0,0 +1,2 @@ +before calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":null} +after calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":42} diff --git a/json-develop/docs/examples/byte_container_with_subtype__subtype.cpp b/json-develop/docs/examples/byte_container_with_subtype__subtype.cpp new file mode 100644 index 0000000..cd230ad --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__subtype.cpp @@ -0,0 +1,22 @@ +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container + auto c1 = byte_container_with_subtype(bytes); + + // create container with subtype + auto c2 = byte_container_with_subtype(bytes, 42); + + std::cout << "c1.subtype() = " << c1.subtype() + << "\nc2.subtype() = " << c2.subtype() << std::endl; + + // in case no subtype is set, return special value + assert(c1.subtype() == static_cast(-1)); +} diff --git a/json-develop/docs/examples/byte_container_with_subtype__subtype.output b/json-develop/docs/examples/byte_container_with_subtype__subtype.output new file mode 100644 index 0000000..4795527 --- /dev/null +++ b/json-develop/docs/examples/byte_container_with_subtype__subtype.output @@ -0,0 +1,2 @@ +c1.subtype() = 18446744073709551615 +c2.subtype() = 42 diff --git a/json-develop/docs/examples/cbegin.cpp b/json-develop/docs/examples/cbegin.cpp new file mode 100644 index 0000000..bed2b37 --- /dev/null +++ b/json-develop/docs/examples/cbegin.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + const json array = {1, 2, 3, 4, 5}; + + // get an iterator to the first element + json::const_iterator it = array.cbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/cbegin.output b/json-develop/docs/examples/cbegin.output new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/json-develop/docs/examples/cbegin.output @@ -0,0 +1 @@ +1 diff --git a/json-develop/docs/examples/cbor_tag_handler_t.cpp b/json-develop/docs/examples/cbor_tag_handler_t.cpp new file mode 100644 index 0000000..79052c7 --- /dev/null +++ b/json-develop/docs/examples/cbor_tag_handler_t.cpp @@ -0,0 +1,28 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // tagged byte string + std::vector vec = {{0xd8, 0x42, 0x44, 0xcA, 0xfe, 0xba, 0xbe}}; + + // cbor_tag_handler_t::error throws + try + { + auto b_throw_on_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::error); + } + catch (json::parse_error& e) + { + std::cout << e.what() << std::endl; + } + + // cbor_tag_handler_t::ignore ignores the tag + auto b_ignore_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore); + std::cout << b_ignore_tag << std::endl; + + // cbor_tag_handler_t::store stores the tag as binary subtype + auto b_store_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::store); + std::cout << b_store_tag << std::endl; +} diff --git a/json-develop/docs/examples/cbor_tag_handler_t.output b/json-develop/docs/examples/cbor_tag_handler_t.output new file mode 100644 index 0000000..18920b1 --- /dev/null +++ b/json-develop/docs/examples/cbor_tag_handler_t.output @@ -0,0 +1,3 @@ +[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xD8 +{"bytes":[202,254,186,190],"subtype":null} +{"bytes":[202,254,186,190],"subtype":66} diff --git a/json-develop/docs/examples/cend.cpp b/json-develop/docs/examples/cend.cpp new file mode 100644 index 0000000..3050f50 --- /dev/null +++ b/json-develop/docs/examples/cend.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to one past the last element + json::const_iterator it = array.cend(); + + // decrement the iterator to point to the last element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/cend.output b/json-develop/docs/examples/cend.output new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/json-develop/docs/examples/cend.output @@ -0,0 +1 @@ +5 diff --git a/json-develop/docs/examples/clear.cpp b/json-develop/docs/examples/clear.cpp new file mode 100644 index 0000000..f081e7e --- /dev/null +++ b/json-develop/docs/examples/clear.cpp @@ -0,0 +1,34 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call clear() + j_null.clear(); + j_boolean.clear(); + j_number_integer.clear(); + j_number_float.clear(); + j_object.clear(); + j_array.clear(); + j_string.clear(); + + // serialize the cleared values() + std::cout << j_null << '\n'; + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} diff --git a/json-develop/docs/examples/clear.output b/json-develop/docs/examples/clear.output new file mode 100644 index 0000000..ea542ca --- /dev/null +++ b/json-develop/docs/examples/clear.output @@ -0,0 +1,7 @@ +null +false +0 +0.0 +{} +[] +"" diff --git a/json-develop/docs/examples/contains__json_pointer.cpp b/json-develop/docs/examples/contains__json_pointer.cpp new file mode 100644 index 0000000..f9de546 --- /dev/null +++ b/json-develop/docs/examples/contains__json_pointer.cpp @@ -0,0 +1,43 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + std::cout << std::boolalpha + << j.contains("/number"_json_pointer) << '\n' + << j.contains("/string"_json_pointer) << '\n' + << j.contains("/array"_json_pointer) << '\n' + << j.contains("/array/1"_json_pointer) << '\n' + << j.contains("/array/-"_json_pointer) << '\n' + << j.contains("/array/4"_json_pointer) << '\n' + << j.contains("/baz"_json_pointer) << std::endl; + + try + { + // try to use an array index with leading '0' + j.contains("/array/01"_json_pointer); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + try + { + // try to use an array index that is not a number + j.contains("/array/one"_json_pointer); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/contains__json_pointer.output b/json-develop/docs/examples/contains__json_pointer.output new file mode 100644 index 0000000..dd1eb38 --- /dev/null +++ b/json-develop/docs/examples/contains__json_pointer.output @@ -0,0 +1,7 @@ +true +true +true +true +false +false +false diff --git a/json-develop/docs/examples/contains__keytype.c++17.cpp b/json-develop/docs/examples/contains__keytype.c++17.cpp new file mode 100644 index 0000000..43b62fa --- /dev/null +++ b/json-develop/docs/examples/contains__keytype.c++17.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create some JSON values + json j_object = R"( {"key": "value"} )"_json; + json j_array = R"( [1, 2, 3] )"_json; + + // call contains + std::cout << std::boolalpha << + "j_object contains 'key': " << j_object.contains("key"sv) << '\n' << + "j_object contains 'another': " << j_object.contains("another"sv) << '\n' << + "j_array contains 'key': " << j_array.contains("key"sv) << std::endl; +} diff --git a/json-develop/docs/examples/contains__keytype.c++17.output b/json-develop/docs/examples/contains__keytype.c++17.output new file mode 100644 index 0000000..14ad177 --- /dev/null +++ b/json-develop/docs/examples/contains__keytype.c++17.output @@ -0,0 +1,3 @@ +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false diff --git a/json-develop/docs/examples/contains__object_t_key_type.cpp b/json-develop/docs/examples/contains__object_t_key_type.cpp new file mode 100644 index 0000000..a8bc814 --- /dev/null +++ b/json-develop/docs/examples/contains__object_t_key_type.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create some JSON values + json j_object = R"( {"key": "value"} )"_json; + json j_array = R"( [1, 2, 3] )"_json; + + // call contains + std::cout << std::boolalpha << + "j_object contains 'key': " << j_object.contains("key") << '\n' << + "j_object contains 'another': " << j_object.contains("another") << '\n' << + "j_array contains 'key': " << j_array.contains("key") << std::endl; +} diff --git a/json-develop/docs/examples/contains__object_t_key_type.output b/json-develop/docs/examples/contains__object_t_key_type.output new file mode 100644 index 0000000..14ad177 --- /dev/null +++ b/json-develop/docs/examples/contains__object_t_key_type.output @@ -0,0 +1,3 @@ +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false diff --git a/json-develop/docs/examples/count__keytype.c++17.cpp b/json-develop/docs/examples/count__keytype.c++17.cpp new file mode 100644 index 0000000..ec6de06 --- /dev/null +++ b/json-develop/docs/examples/count__keytype.c++17.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call count() + auto count_two = j_object.count("two"sv); + auto count_three = j_object.count("three"sv); + + // print values + std::cout << "number of elements with key \"two\": " << count_two << '\n'; + std::cout << "number of elements with key \"three\": " << count_three << '\n'; +} diff --git a/json-develop/docs/examples/count__keytype.c++17.output b/json-develop/docs/examples/count__keytype.c++17.output new file mode 100644 index 0000000..d816fcb --- /dev/null +++ b/json-develop/docs/examples/count__keytype.c++17.output @@ -0,0 +1,2 @@ +number of elements with key "two": 1 +number of elements with key "three": 0 diff --git a/json-develop/docs/examples/count__object_t_key_type.cpp b/json-develop/docs/examples/count__object_t_key_type.cpp new file mode 100644 index 0000000..a8d54b9 --- /dev/null +++ b/json-develop/docs/examples/count__object_t_key_type.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call count() + auto count_two = j_object.count("two"); + auto count_three = j_object.count("three"); + + // print values + std::cout << "number of elements with key \"two\": " << count_two << '\n'; + std::cout << "number of elements with key \"three\": " << count_three << '\n'; +} diff --git a/json-develop/docs/examples/count__object_t_key_type.output b/json-develop/docs/examples/count__object_t_key_type.output new file mode 100644 index 0000000..d816fcb --- /dev/null +++ b/json-develop/docs/examples/count__object_t_key_type.output @@ -0,0 +1,2 @@ +number of elements with key "two": 1 +number of elements with key "three": 0 diff --git a/json-develop/docs/examples/crbegin.cpp b/json-develop/docs/examples/crbegin.cpp new file mode 100644 index 0000000..dc3209c --- /dev/null +++ b/json-develop/docs/examples/crbegin.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-beginning + json::const_reverse_iterator it = array.crbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/crbegin.output b/json-develop/docs/examples/crbegin.output new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/json-develop/docs/examples/crbegin.output @@ -0,0 +1 @@ +5 diff --git a/json-develop/docs/examples/crend.cpp b/json-develop/docs/examples/crend.cpp new file mode 100644 index 0000000..dff2609 --- /dev/null +++ b/json-develop/docs/examples/crend.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-end + json::const_reverse_iterator it = array.crend(); + + // increment the iterator to point to the first element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/crend.output b/json-develop/docs/examples/crend.output new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/json-develop/docs/examples/crend.output @@ -0,0 +1 @@ +1 diff --git a/json-develop/docs/examples/default_object_comparator_t.cpp b/json-develop/docs/examples/default_object_comparator_t.cpp new file mode 100644 index 0000000..9f200fe --- /dev/null +++ b/json-develop/docs/examples/default_object_comparator_t.cpp @@ -0,0 +1,11 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha + << "one < two : " << json::default_object_comparator_t{}("one", "two") << "\n" + << "three < four : " << json::default_object_comparator_t{}("three", "four") << std::endl; +} diff --git a/json-develop/docs/examples/default_object_comparator_t.output b/json-develop/docs/examples/default_object_comparator_t.output new file mode 100644 index 0000000..b1daf3b --- /dev/null +++ b/json-develop/docs/examples/default_object_comparator_t.output @@ -0,0 +1,2 @@ +one < two : true +three < four : false diff --git a/json-develop/docs/examples/diagnostics_extended.cpp b/json-develop/docs/examples/diagnostics_extended.cpp new file mode 100644 index 0000000..f4c43f0 --- /dev/null +++ b/json-develop/docs/examples/diagnostics_extended.cpp @@ -0,0 +1,22 @@ +#include + +# define JSON_DIAGNOSTICS 1 +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["address"]["street"] = "Fake Street"; + j["address"]["housenumber"] = "12"; + + try + { + int housenumber = j["address"]["housenumber"]; + } + catch (json::exception& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/diagnostics_extended.output b/json-develop/docs/examples/diagnostics_extended.output new file mode 100644 index 0000000..f142927 --- /dev/null +++ b/json-develop/docs/examples/diagnostics_extended.output @@ -0,0 +1 @@ +[json.exception.type_error.302] (/address/housenumber) type must be number, but is string diff --git a/json-develop/docs/examples/diagnostics_standard.cpp b/json-develop/docs/examples/diagnostics_standard.cpp new file mode 100644 index 0000000..575c409 --- /dev/null +++ b/json-develop/docs/examples/diagnostics_standard.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["address"]["street"] = "Fake Street"; + j["address"]["housenumber"] = "12"; + + try + { + int housenumber = j["address"]["housenumber"]; + } + catch (json::exception& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/diagnostics_standard.output b/json-develop/docs/examples/diagnostics_standard.output new file mode 100644 index 0000000..79707a0 --- /dev/null +++ b/json-develop/docs/examples/diagnostics_standard.output @@ -0,0 +1 @@ +[json.exception.type_error.302] type must be number, but is string diff --git a/json-develop/docs/examples/diff.cpp b/json-develop/docs/examples/diff.cpp new file mode 100644 index 0000000..ef01332 --- /dev/null +++ b/json-develop/docs/examples/diff.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the source document + json source = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the target document + json target = R"( + { + "baz": "boo", + "hello": [ + "world" + ] + } + )"_json; + + // create the patch + json patch = json::diff(source, target); + + // roundtrip + json patched_source = source.patch(patch); + + // output patch and roundtrip result + std::cout << std::setw(4) << patch << "\n\n" + << std::setw(4) << patched_source << std::endl; +} diff --git a/json-develop/docs/examples/diff.output b/json-develop/docs/examples/diff.output new file mode 100644 index 0000000..7dc7979 --- /dev/null +++ b/json-develop/docs/examples/diff.output @@ -0,0 +1,25 @@ +[ + { + "op": "replace", + "path": "/baz", + "value": "boo" + }, + { + "op": "remove", + "path": "/foo" + }, + { + "op": "add", + "path": "/hello", + "value": [ + "world" + ] + } +] + +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/json-develop/docs/examples/dump.cpp b/json-develop/docs/examples/dump.cpp new file mode 100644 index 0000000..eb2d71f --- /dev/null +++ b/json-develop/docs/examples/dump.cpp @@ -0,0 +1,48 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hellö 😀!"; + + // call dump() + std::cout << "objects:" << '\n' + << j_object.dump() << "\n\n" + << j_object.dump(-1) << "\n\n" + << j_object.dump(0) << "\n\n" + << j_object.dump(4) << "\n\n" + << j_object.dump(1, '\t') << "\n\n"; + + std::cout << "arrays:" << '\n' + << j_array.dump() << "\n\n" + << j_array.dump(-1) << "\n\n" + << j_array.dump(0) << "\n\n" + << j_array.dump(4) << "\n\n" + << j_array.dump(1, '\t') << "\n\n"; + + std::cout << "strings:" << '\n' + << j_string.dump() << '\n' + << j_string.dump(-1, ' ', true) << '\n'; + + // create JSON value with invalid UTF-8 byte sequence + json j_invalid = "ä\xA9ü"; + try + { + std::cout << j_invalid.dump() << std::endl; + } + catch (json::type_error& e) + { + std::cout << e.what() << std::endl; + } + + std::cout << "string with replaced invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace) + << "\nstring with ignored invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore) + << '\n'; +} diff --git a/json-develop/docs/examples/dump.output b/json-develop/docs/examples/dump.output new file mode 100644 index 0000000..43009fe --- /dev/null +++ b/json-develop/docs/examples/dump.output @@ -0,0 +1,55 @@ +objects: +{"one":1,"two":2} + +{"one":1,"two":2} + +{ +"one": 1, +"two": 2 +} + +{ + "one": 1, + "two": 2 +} + +{ + "one": 1, + "two": 2 +} + +arrays: +[1,2,4,8,16] + +[1,2,4,8,16] + +[ +1, +2, +4, +8, +16 +] + +[ + 1, + 2, + 4, + 8, + 16 +] + +[ + 1, + 2, + 4, + 8, + 16 +] + +strings: +"Hellö 😀!" +"Hell\u00f6 \ud83d\ude00!" +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" diff --git a/json-develop/docs/examples/emplace.cpp b/json-develop/docs/examples/emplace.cpp new file mode 100644 index 0000000..a531491 --- /dev/null +++ b/json-develop/docs/examples/emplace.cpp @@ -0,0 +1,31 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + auto res1 = object.emplace("three", 3); + null.emplace("A", "a"); + null.emplace("B", "b"); + + // the following call will not add an object, because there is already + // a value stored at key "B" + auto res2 = null.emplace("B", "c"); + + // print values + std::cout << object << '\n'; + std::cout << *res1.first << " " << std::boolalpha << res1.second << '\n'; + + std::cout << null << '\n'; + std::cout << *res2.first << " " << std::boolalpha << res2.second << '\n'; +} diff --git a/json-develop/docs/examples/emplace.output b/json-develop/docs/examples/emplace.output new file mode 100644 index 0000000..83d6f77 --- /dev/null +++ b/json-develop/docs/examples/emplace.output @@ -0,0 +1,6 @@ +{"one":1,"two":2} +null +{"one":1,"three":3,"two":2} +3 true +{"A":"a","B":"b"} +"b" false diff --git a/json-develop/docs/examples/emplace_back.cpp b/json-develop/docs/examples/emplace_back.cpp new file mode 100644 index 0000000..e979a94 --- /dev/null +++ b/json-develop/docs/examples/emplace_back.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.emplace_back(6); + null.emplace_back("first"); + null.emplace_back(3, "second"); + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} diff --git a/json-develop/docs/examples/emplace_back.output b/json-develop/docs/examples/emplace_back.output new file mode 100644 index 0000000..bdd80d8 --- /dev/null +++ b/json-develop/docs/examples/emplace_back.output @@ -0,0 +1,4 @@ +[1,2,3,4,5] +null +[1,2,3,4,5,6] +["first",["second","second","second"]] diff --git a/json-develop/docs/examples/empty.cpp b/json-develop/docs/examples/empty.cpp new file mode 100644 index 0000000..6ef6e40 --- /dev/null +++ b/json-develop/docs/examples/empty.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call empty() + std::cout << std::boolalpha; + std::cout << j_null.empty() << '\n'; + std::cout << j_boolean.empty() << '\n'; + std::cout << j_number_integer.empty() << '\n'; + std::cout << j_number_float.empty() << '\n'; + std::cout << j_object.empty() << '\n'; + std::cout << j_object_empty.empty() << '\n'; + std::cout << j_array.empty() << '\n'; + std::cout << j_array_empty.empty() << '\n'; + std::cout << j_string.empty() << '\n'; +} diff --git a/json-develop/docs/examples/empty.output b/json-develop/docs/examples/empty.output new file mode 100644 index 0000000..d071a39 --- /dev/null +++ b/json-develop/docs/examples/empty.output @@ -0,0 +1,9 @@ +true +false +false +false +false +true +false +true +false diff --git a/json-develop/docs/examples/end.cpp b/json-develop/docs/examples/end.cpp new file mode 100644 index 0000000..47beedb --- /dev/null +++ b/json-develop/docs/examples/end.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to one past the last element + json::iterator it = array.end(); + + // decrement the iterator to point to the last element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/end.output b/json-develop/docs/examples/end.output new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/json-develop/docs/examples/end.output @@ -0,0 +1 @@ +5 diff --git a/json-develop/docs/examples/erase__IteratorType.cpp b/json-develop/docs/examples/erase__IteratorType.cpp new file mode 100644 index 0000000..f0d4ec6 --- /dev/null +++ b/json-develop/docs/examples/erase__IteratorType.cpp @@ -0,0 +1,31 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call erase() + j_boolean.erase(j_boolean.begin()); + j_number_integer.erase(j_number_integer.begin()); + j_number_float.erase(j_number_float.begin()); + j_object.erase(j_object.find("two")); + j_array.erase(j_array.begin() + 2); + j_string.erase(j_string.begin()); + + // print values + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} diff --git a/json-develop/docs/examples/erase__IteratorType.output b/json-develop/docs/examples/erase__IteratorType.output new file mode 100644 index 0000000..e392f8e --- /dev/null +++ b/json-develop/docs/examples/erase__IteratorType.output @@ -0,0 +1,6 @@ +null +null +null +{"one":1} +[1,2,8,16] +null diff --git a/json-develop/docs/examples/erase__IteratorType_IteratorType.cpp b/json-develop/docs/examples/erase__IteratorType_IteratorType.cpp new file mode 100644 index 0000000..392511f --- /dev/null +++ b/json-develop/docs/examples/erase__IteratorType_IteratorType.cpp @@ -0,0 +1,31 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call erase() + j_boolean.erase(j_boolean.begin(), j_boolean.end()); + j_number_integer.erase(j_number_integer.begin(), j_number_integer.end()); + j_number_float.erase(j_number_float.begin(), j_number_float.end()); + j_object.erase(j_object.find("two"), j_object.end()); + j_array.erase(j_array.begin() + 1, j_array.begin() + 3); + j_string.erase(j_string.begin(), j_string.end()); + + // print values + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} diff --git a/json-develop/docs/examples/erase__IteratorType_IteratorType.output b/json-develop/docs/examples/erase__IteratorType_IteratorType.output new file mode 100644 index 0000000..5d01f00 --- /dev/null +++ b/json-develop/docs/examples/erase__IteratorType_IteratorType.output @@ -0,0 +1,6 @@ +null +null +null +{"one":1} +[1,8,16] +null diff --git a/json-develop/docs/examples/erase__keytype.c++17.cpp b/json-develop/docs/examples/erase__keytype.c++17.cpp new file mode 100644 index 0000000..c5e4bed --- /dev/null +++ b/json-develop/docs/examples/erase__keytype.c++17.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call erase() + auto count_one = j_object.erase("one"sv); + auto count_three = j_object.erase("three"sv); + + // print values + std::cout << j_object << '\n'; + std::cout << count_one << " " << count_three << '\n'; +} diff --git a/json-develop/docs/examples/erase__keytype.c++17.output b/json-develop/docs/examples/erase__keytype.c++17.output new file mode 100644 index 0000000..28d7939 --- /dev/null +++ b/json-develop/docs/examples/erase__keytype.c++17.output @@ -0,0 +1,2 @@ +{"two":2} +1 0 diff --git a/json-develop/docs/examples/erase__object_t_key_type.cpp b/json-develop/docs/examples/erase__object_t_key_type.cpp new file mode 100644 index 0000000..2fd84c8 --- /dev/null +++ b/json-develop/docs/examples/erase__object_t_key_type.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call erase() + auto count_one = j_object.erase("one"); + auto count_three = j_object.erase("three"); + + // print values + std::cout << j_object << '\n'; + std::cout << count_one << " " << count_three << '\n'; +} diff --git a/json-develop/docs/examples/erase__object_t_key_type.output b/json-develop/docs/examples/erase__object_t_key_type.output new file mode 100644 index 0000000..28d7939 --- /dev/null +++ b/json-develop/docs/examples/erase__object_t_key_type.output @@ -0,0 +1,2 @@ +{"two":2} +1 0 diff --git a/json-develop/docs/examples/erase__size_type.cpp b/json-develop/docs/examples/erase__size_type.cpp new file mode 100644 index 0000000..8100623 --- /dev/null +++ b/json-develop/docs/examples/erase__size_type.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json j_array = {0, 1, 2, 3, 4, 5}; + + // call erase() + j_array.erase(2); + + // print values + std::cout << j_array << '\n'; +} diff --git a/json-develop/docs/examples/erase__size_type.output b/json-develop/docs/examples/erase__size_type.output new file mode 100644 index 0000000..4ad7406 --- /dev/null +++ b/json-develop/docs/examples/erase__size_type.output @@ -0,0 +1 @@ +[0,1,3,4,5] diff --git a/json-develop/docs/examples/error_handler_t.cpp b/json-develop/docs/examples/error_handler_t.cpp new file mode 100644 index 0000000..add3f3b --- /dev/null +++ b/json-develop/docs/examples/error_handler_t.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value with invalid UTF-8 byte sequence + json j_invalid = "ä\xA9ü"; + try + { + std::cout << j_invalid.dump() << std::endl; + } + catch (json::type_error& e) + { + std::cout << e.what() << std::endl; + } + + std::cout << "string with replaced invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace) + << "\nstring with ignored invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore) + << '\n'; +} diff --git a/json-develop/docs/examples/error_handler_t.output b/json-develop/docs/examples/error_handler_t.output new file mode 100644 index 0000000..718d62b --- /dev/null +++ b/json-develop/docs/examples/error_handler_t.output @@ -0,0 +1,3 @@ +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" diff --git a/json-develop/docs/examples/exception.cpp b/json-develop/docs/examples/exception.cpp new file mode 100644 index 0000000..82696e6 --- /dev/null +++ b/json-develop/docs/examples/exception.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling at() for a non-existing key + json j = {{"foo", "bar"}}; + json k = j.at("non-existing"); + } + catch (json::exception& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/json-develop/docs/examples/exception.output b/json-develop/docs/examples/exception.output new file mode 100644 index 0000000..fa20df6 --- /dev/null +++ b/json-develop/docs/examples/exception.output @@ -0,0 +1,2 @@ +message: [json.exception.out_of_range.403] key 'non-existing' not found +exception id: 403 diff --git a/json-develop/docs/examples/find__keytype.c++17.cpp b/json-develop/docs/examples/find__keytype.c++17.cpp new file mode 100644 index 0000000..da94cf0 --- /dev/null +++ b/json-develop/docs/examples/find__keytype.c++17.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call find + auto it_two = j_object.find("two"sv); + auto it_three = j_object.find("three"sv); + + // print values + std::cout << std::boolalpha; + std::cout << "\"two\" was found: " << (it_two != j_object.end()) << '\n'; + std::cout << "value at key \"two\": " << *it_two << '\n'; + std::cout << "\"three\" was found: " << (it_three != j_object.end()) << '\n'; +} diff --git a/json-develop/docs/examples/find__keytype.c++17.output b/json-develop/docs/examples/find__keytype.c++17.output new file mode 100644 index 0000000..509bb42 --- /dev/null +++ b/json-develop/docs/examples/find__keytype.c++17.output @@ -0,0 +1,3 @@ +"two" was found: true +value at key "two": 2 +"three" was found: false diff --git a/json-develop/docs/examples/find__object_t_key_type.cpp b/json-develop/docs/examples/find__object_t_key_type.cpp new file mode 100644 index 0000000..685ba77 --- /dev/null +++ b/json-develop/docs/examples/find__object_t_key_type.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call find + auto it_two = j_object.find("two"); + auto it_three = j_object.find("three"); + + // print values + std::cout << std::boolalpha; + std::cout << "\"two\" was found: " << (it_two != j_object.end()) << '\n'; + std::cout << "value at key \"two\": " << *it_two << '\n'; + std::cout << "\"three\" was found: " << (it_three != j_object.end()) << '\n'; +} diff --git a/json-develop/docs/examples/find__object_t_key_type.output b/json-develop/docs/examples/find__object_t_key_type.output new file mode 100644 index 0000000..509bb42 --- /dev/null +++ b/json-develop/docs/examples/find__object_t_key_type.output @@ -0,0 +1,3 @@ +"two" was found: true +value at key "two": 2 +"three" was found: false diff --git a/json-develop/docs/examples/flatten.cpp b/json-develop/docs/examples/flatten.cpp new file mode 100644 index 0000000..83f3ff6 --- /dev/null +++ b/json-develop/docs/examples/flatten.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value + json j = + { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + { + "answer", { + {"everything", 42} + } + }, + {"list", {1, 0, 2}}, + { + "object", { + {"currency", "USD"}, + {"value", 42.99} + } + } + }; + + // call flatten() + std::cout << std::setw(4) << j.flatten() << '\n'; +} diff --git a/json-develop/docs/examples/flatten.output b/json-develop/docs/examples/flatten.output new file mode 100644 index 0000000..33bd4c4 --- /dev/null +++ b/json-develop/docs/examples/flatten.output @@ -0,0 +1,12 @@ +{ + "/answer/everything": 42, + "/happy": true, + "/list/0": 1, + "/list/1": 0, + "/list/2": 2, + "/name": "Niels", + "/nothing": null, + "/object/currency": "USD", + "/object/value": 42.99, + "/pi": 3.141 +} diff --git a/json-develop/docs/examples/from_bjdata.cpp b/json-develop/docs/examples/from_bjdata.cpp new file mode 100644 index 0000000..961164c --- /dev/null +++ b/json-develop/docs/examples/from_bjdata.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, + 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + }; + + // deserialize it with BJData + json j = json::from_bjdata(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} diff --git a/json-develop/docs/examples/from_bjdata.output b/json-develop/docs/examples/from_bjdata.output new file mode 100644 index 0000000..259f63b --- /dev/null +++ b/json-develop/docs/examples/from_bjdata.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/json-develop/docs/examples/from_bson.cpp b/json-develop/docs/examples/from_bson.cpp new file mode 100644 index 0000000..c9d9fdf --- /dev/null +++ b/json-develop/docs/examples/from_bson.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + + // deserialize it with BSON + json j = json::from_bson(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} diff --git a/json-develop/docs/examples/from_bson.output b/json-develop/docs/examples/from_bson.output new file mode 100644 index 0000000..259f63b --- /dev/null +++ b/json-develop/docs/examples/from_bson.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/json-develop/docs/examples/from_cbor.cpp b/json-develop/docs/examples/from_cbor.cpp new file mode 100644 index 0000000..e685329 --- /dev/null +++ b/json-develop/docs/examples/from_cbor.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, + 0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x00 + }; + + // deserialize it with CBOR + json j = json::from_cbor(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} diff --git a/json-develop/docs/examples/from_cbor.output b/json-develop/docs/examples/from_cbor.output new file mode 100644 index 0000000..259f63b --- /dev/null +++ b/json-develop/docs/examples/from_cbor.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/json-develop/docs/examples/from_json__default_constructible.cpp b/json-develop/docs/examples/from_json__default_constructible.cpp new file mode 100644 index 0000000..17c0551 --- /dev/null +++ b/json-develop/docs/examples/from_json__default_constructible.cpp @@ -0,0 +1,37 @@ +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person +struct person +{ + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace ns +{ +void from_json(const json& j, person& p) +{ + j.at("name").get_to(p.name); + j.at("address").get_to(p.address); + j.at("age").get_to(p.age); +} +} // namespace ns + +int main() +{ + json j; + j["name"] = "Ned Flanders"; + j["address"] = "744 Evergreen Terrace"; + j["age"] = 60; + + auto p = j.get(); + + std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; +} diff --git a/json-develop/docs/examples/from_json__default_constructible.output b/json-develop/docs/examples/from_json__default_constructible.output new file mode 100644 index 0000000..b924523 --- /dev/null +++ b/json-develop/docs/examples/from_json__default_constructible.output @@ -0,0 +1 @@ +Ned Flanders (60) lives in 744 Evergreen Terrace diff --git a/json-develop/docs/examples/from_json__non_default_constructible.cpp b/json-develop/docs/examples/from_json__non_default_constructible.cpp new file mode 100644 index 0000000..6cb8615 --- /dev/null +++ b/json-develop/docs/examples/from_json__non_default_constructible.cpp @@ -0,0 +1,53 @@ +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person (not default constructible) +struct person +{ + person(std::string n, std::string a, int aa) + : name(std::move(n)), address(std::move(a)), age(aa) + {} + + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace nlohmann +{ +template <> +struct adl_serializer +{ + static ns::person from_json(const json& j) + { + return {j.at("name"), j.at("address"), j.at("age")}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert person to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, ns::person p) + { + j["name"] = p.name; + j["address"] = p.address; + j["age"] = p.age; + } +}; +} // namespace nlohmann + +int main() +{ + json j; + j["name"] = "Ned Flanders"; + j["address"] = "744 Evergreen Terrace"; + j["age"] = 60; + + auto p = j.get(); + + std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; +} diff --git a/json-develop/docs/examples/from_json__non_default_constructible.output b/json-develop/docs/examples/from_json__non_default_constructible.output new file mode 100644 index 0000000..b924523 --- /dev/null +++ b/json-develop/docs/examples/from_json__non_default_constructible.output @@ -0,0 +1 @@ +Ned Flanders (60) lives in 744 Evergreen Terrace diff --git a/json-develop/docs/examples/from_msgpack.cpp b/json-develop/docs/examples/from_msgpack.cpp new file mode 100644 index 0000000..5c2183f --- /dev/null +++ b/json-develop/docs/examples/from_msgpack.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, + 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x00 + }; + + // deserialize it with MessagePack + json j = json::from_msgpack(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} diff --git a/json-develop/docs/examples/from_msgpack.output b/json-develop/docs/examples/from_msgpack.output new file mode 100644 index 0000000..259f63b --- /dev/null +++ b/json-develop/docs/examples/from_msgpack.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/json-develop/docs/examples/from_ubjson.cpp b/json-develop/docs/examples/from_ubjson.cpp new file mode 100644 index 0000000..1e85e4e --- /dev/null +++ b/json-develop/docs/examples/from_ubjson.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, + 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + }; + + // deserialize it with UBJSON + json j = json::from_ubjson(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} diff --git a/json-develop/docs/examples/from_ubjson.output b/json-develop/docs/examples/from_ubjson.output new file mode 100644 index 0000000..259f63b --- /dev/null +++ b/json-develop/docs/examples/from_ubjson.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/json-develop/docs/examples/front.cpp b/json-develop/docs/examples/front.cpp new file mode 100644 index 0000000..a0f6306 --- /dev/null +++ b/json-develop/docs/examples/front.cpp @@ -0,0 +1,29 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call front() + //std::cout << j_null.front() << '\n'; // would throw + std::cout << j_boolean.front() << '\n'; + std::cout << j_number_integer.front() << '\n'; + std::cout << j_number_float.front() << '\n'; + std::cout << j_object.front() << '\n'; + //std::cout << j_object_empty.front() << '\n'; // undefined behavior + std::cout << j_array.front() << '\n'; + //std::cout << j_array_empty.front() << '\n'; // undefined behavior + std::cout << j_string.front() << '\n'; +} diff --git a/json-develop/docs/examples/front.output b/json-develop/docs/examples/front.output new file mode 100644 index 0000000..6301db5 --- /dev/null +++ b/json-develop/docs/examples/front.output @@ -0,0 +1,6 @@ +true +17 +23.42 +1 +1 +"Hello, world" diff --git a/json-develop/docs/examples/get__PointerType.cpp b/json-develop/docs/examples/get__PointerType.cpp new file mode 100644 index 0000000..2f32ed7 --- /dev/null +++ b/json-develop/docs/examples/get__PointerType.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting pointers + auto p1 = value.get(); + auto p2 = value.get(); + auto p3 = value.get(); + auto p4 = value.get(); + auto p5 = value.get(); + + // print the pointees + std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n'; + std::cout << std::boolalpha << (p5 == nullptr) << '\n'; +} diff --git a/json-develop/docs/examples/get__PointerType.output b/json-develop/docs/examples/get__PointerType.output new file mode 100644 index 0000000..a15dd77 --- /dev/null +++ b/json-develop/docs/examples/get__PointerType.output @@ -0,0 +1,2 @@ +17 17 17 17 +true diff --git a/json-develop/docs/examples/get__ValueType_const.cpp b/json-develop/docs/examples/get__ValueType_const.cpp new file mode 100644 index 0000000..7a703aa --- /dev/null +++ b/json-develop/docs/examples/get__ValueType_const.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + // use explicit conversions + auto v1 = json_types["boolean"].get(); + auto v2 = json_types["number"]["integer"].get(); + auto v3 = json_types["number"]["integer"].get(); + auto v4 = json_types["number"]["floating-point"].get(); + auto v5 = json_types["number"]["floating-point"].get(); + auto v6 = json_types["string"].get(); + auto v7 = json_types["array"].get>(); + auto v8 = json_types.get>(); + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } +} diff --git a/json-develop/docs/examples/get__ValueType_const.output b/json-develop/docs/examples/get__ValueType_const.output new file mode 100644 index 0000000..5cd9cd3 --- /dev/null +++ b/json-develop/docs/examples/get__ValueType_const.output @@ -0,0 +1,11 @@ +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] diff --git a/json-develop/docs/examples/get_allocator.cpp b/json-develop/docs/examples/get_allocator.cpp new file mode 100644 index 0000000..35079a1 --- /dev/null +++ b/json-develop/docs/examples/get_allocator.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + auto alloc = json::get_allocator(); + using traits_t = std::allocator_traits; + + json* j = traits_t::allocate(alloc, 1); + traits_t::construct(alloc, j, "Hello, world!"); + + std::cout << *j << std::endl; + + traits_t::destroy(alloc, j); + traits_t::deallocate(alloc, j, 1); +} diff --git a/json-develop/docs/examples/get_allocator.output b/json-develop/docs/examples/get_allocator.output new file mode 100644 index 0000000..8effb3e --- /dev/null +++ b/json-develop/docs/examples/get_allocator.output @@ -0,0 +1 @@ +"Hello, world!" diff --git a/json-develop/docs/examples/get_binary.cpp b/json-develop/docs/examples/get_binary.cpp new file mode 100644 index 0000000..617ce60 --- /dev/null +++ b/json-develop/docs/examples/get_binary.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a binary vector + std::vector vec = {0xCA, 0xFE, 0xBA, 0xBE}; + + // create a binary JSON value with subtype 42 + json j = json::binary(vec, 42); + + // output type and subtype + std::cout << "type: " << j.type_name() << ", subtype: " << j.get_binary().subtype() << std::endl; +} diff --git a/json-develop/docs/examples/get_binary.output b/json-develop/docs/examples/get_binary.output new file mode 100644 index 0000000..74b05d2 --- /dev/null +++ b/json-develop/docs/examples/get_binary.output @@ -0,0 +1 @@ +type: binary, subtype: 42 diff --git a/json-develop/docs/examples/get_ptr.cpp b/json-develop/docs/examples/get_ptr.cpp new file mode 100644 index 0000000..564ce0f --- /dev/null +++ b/json-develop/docs/examples/get_ptr.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting pointers + auto p1 = value.get_ptr(); + auto p2 = value.get_ptr(); + auto p3 = value.get_ptr(); + auto p4 = value.get_ptr(); + auto p5 = value.get_ptr(); + + // print the pointees + std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n'; + std::cout << std::boolalpha << (p5 == nullptr) << '\n'; +} diff --git a/json-develop/docs/examples/get_ptr.output b/json-develop/docs/examples/get_ptr.output new file mode 100644 index 0000000..a15dd77 --- /dev/null +++ b/json-develop/docs/examples/get_ptr.output @@ -0,0 +1,2 @@ +17 17 17 17 +true diff --git a/json-develop/docs/examples/get_ref.cpp b/json-develop/docs/examples/get_ref.cpp new file mode 100644 index 0000000..ab25946 --- /dev/null +++ b/json-develop/docs/examples/get_ref.cpp @@ -0,0 +1,27 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting references + auto r1 = value.get_ref(); + auto r2 = value.get_ref(); + + // print the values + std::cout << r1 << ' ' << r2 << '\n'; + + // incompatible type throws exception + try + { + auto r3 = value.get_ref(); + } + catch (json::type_error& ex) + { + std::cout << ex.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/get_ref.output b/json-develop/docs/examples/get_ref.output new file mode 100644 index 0000000..3811afa --- /dev/null +++ b/json-develop/docs/examples/get_ref.output @@ -0,0 +1,2 @@ +17 17 +[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number diff --git a/json-develop/docs/examples/get_to.cpp b/json-develop/docs/examples/get_to.cpp new file mode 100644 index 0000000..4705b17 --- /dev/null +++ b/json-develop/docs/examples/get_to.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + bool v1; + int v2; + short v3; + float v4; + int v5; + std::string v6; + std::vector v7; + std::unordered_map v8; + + + // use explicit conversions + json_types["boolean"].get_to(v1); + json_types["number"]["integer"].get_to(v2); + json_types["number"]["integer"].get_to(v3); + json_types["number"]["floating-point"].get_to(v4); + json_types["number"]["floating-point"].get_to(v5); + json_types["string"].get_to(v6); + json_types["array"].get_to(v7); + json_types.get_to(v8); + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } +} diff --git a/json-develop/docs/examples/get_to.output b/json-develop/docs/examples/get_to.output new file mode 100644 index 0000000..5cd9cd3 --- /dev/null +++ b/json-develop/docs/examples/get_to.output @@ -0,0 +1,11 @@ +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] diff --git a/json-develop/docs/examples/insert.cpp b/json-develop/docs/examples/insert.cpp new file mode 100644 index 0000000..4ee6098 --- /dev/null +++ b/json-develop/docs/examples/insert.cpp @@ -0,0 +1,17 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert number 10 before number 3 + auto new_pos = v.insert(v.begin() + 2, 10); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} diff --git a/json-develop/docs/examples/insert.output b/json-develop/docs/examples/insert.output new file mode 100644 index 0000000..ed5cab1 --- /dev/null +++ b/json-develop/docs/examples/insert.output @@ -0,0 +1,2 @@ +10 +[1,2,10,3,4] diff --git a/json-develop/docs/examples/insert__count.cpp b/json-develop/docs/examples/insert__count.cpp new file mode 100644 index 0000000..ce33b93 --- /dev/null +++ b/json-develop/docs/examples/insert__count.cpp @@ -0,0 +1,17 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert number 7 copies of number 7 before number 3 + auto new_pos = v.insert(v.begin() + 2, 7, 7); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} diff --git a/json-develop/docs/examples/insert__count.output b/json-develop/docs/examples/insert__count.output new file mode 100644 index 0000000..294685a --- /dev/null +++ b/json-develop/docs/examples/insert__count.output @@ -0,0 +1,2 @@ +7 +[1,2,7,7,7,7,7,7,7,3,4] diff --git a/json-develop/docs/examples/insert__ilist.cpp b/json-develop/docs/examples/insert__ilist.cpp new file mode 100644 index 0000000..a20766a --- /dev/null +++ b/json-develop/docs/examples/insert__ilist.cpp @@ -0,0 +1,17 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert range from v2 before the end of array v + auto new_pos = v.insert(v.end(), {7, 8, 9}); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} diff --git a/json-develop/docs/examples/insert__ilist.output b/json-develop/docs/examples/insert__ilist.output new file mode 100644 index 0000000..b2fc7ee --- /dev/null +++ b/json-develop/docs/examples/insert__ilist.output @@ -0,0 +1,2 @@ +7 +[1,2,3,4,7,8,9] diff --git a/json-develop/docs/examples/insert__range.cpp b/json-develop/docs/examples/insert__range.cpp new file mode 100644 index 0000000..92fe63b --- /dev/null +++ b/json-develop/docs/examples/insert__range.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // create a JSON array to copy values from + json v2 = {"one", "two", "three", "four"}; + + // insert range from v2 before the end of array v + auto new_pos = v.insert(v.end(), v2.begin(), v2.end()); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} diff --git a/json-develop/docs/examples/insert__range.output b/json-develop/docs/examples/insert__range.output new file mode 100644 index 0000000..d50e9f6 --- /dev/null +++ b/json-develop/docs/examples/insert__range.output @@ -0,0 +1,2 @@ +"one" +[1,2,3,4,"one","two","three","four"] diff --git a/json-develop/docs/examples/insert__range_object.cpp b/json-develop/docs/examples/insert__range_object.cpp new file mode 100644 index 0000000..97373d3 --- /dev/null +++ b/json-develop/docs/examples/insert__range_object.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create two JSON objects + json j1 = {{"one", "eins"}, {"two", "zwei"}}; + json j2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}}; + + // output objects + std::cout << j1 << '\n'; + std::cout << j2 << '\n'; + + // insert range from j2 to j1 + j1.insert(j2.begin(), j2.end()); + + // output result of insert call + std::cout << j1 << '\n'; +} diff --git a/json-develop/docs/examples/insert__range_object.output b/json-develop/docs/examples/insert__range_object.output new file mode 100644 index 0000000..a598515 --- /dev/null +++ b/json-develop/docs/examples/insert__range_object.output @@ -0,0 +1,3 @@ +{"one":"eins","two":"zwei"} +{"eleven":"elf","seventeen":"siebzehn"} +{"eleven":"elf","one":"eins","seventeen":"siebzehn","two":"zwei"} diff --git a/json-develop/docs/examples/invalid_iterator.cpp b/json-develop/docs/examples/invalid_iterator.cpp new file mode 100644 index 0000000..5d3e622 --- /dev/null +++ b/json-develop/docs/examples/invalid_iterator.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling iterator::key() on non-object iterator + json j = "string"; + json::iterator it = j.begin(); + auto k = it.key(); + } + catch (json::invalid_iterator& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/json-develop/docs/examples/invalid_iterator.output b/json-develop/docs/examples/invalid_iterator.output new file mode 100644 index 0000000..8668c16 --- /dev/null +++ b/json-develop/docs/examples/invalid_iterator.output @@ -0,0 +1,2 @@ +message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators +exception id: 207 diff --git a/json-develop/docs/examples/is_array.cpp b/json-develop/docs/examples/is_array.cpp new file mode 100644 index 0000000..8ecc450 --- /dev/null +++ b/json-develop/docs/examples/is_array.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_array() + std::cout << std::boolalpha; + std::cout << j_null.is_array() << '\n'; + std::cout << j_boolean.is_array() << '\n'; + std::cout << j_number_integer.is_array() << '\n'; + std::cout << j_number_unsigned_integer.is_array() << '\n'; + std::cout << j_number_float.is_array() << '\n'; + std::cout << j_object.is_array() << '\n'; + std::cout << j_array.is_array() << '\n'; + std::cout << j_string.is_array() << '\n'; + std::cout << j_binary.is_array() << '\n'; +} diff --git a/json-develop/docs/examples/is_array.output b/json-develop/docs/examples/is_array.output new file mode 100644 index 0000000..7b7ef3f --- /dev/null +++ b/json-develop/docs/examples/is_array.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +true +false +false diff --git a/json-develop/docs/examples/is_binary.cpp b/json-develop/docs/examples/is_binary.cpp new file mode 100644 index 0000000..d7f049e --- /dev/null +++ b/json-develop/docs/examples/is_binary.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_binary() + std::cout << std::boolalpha; + std::cout << j_null.is_binary() << '\n'; + std::cout << j_boolean.is_binary() << '\n'; + std::cout << j_number_integer.is_binary() << '\n'; + std::cout << j_number_unsigned_integer.is_binary() << '\n'; + std::cout << j_number_float.is_binary() << '\n'; + std::cout << j_object.is_binary() << '\n'; + std::cout << j_array.is_binary() << '\n'; + std::cout << j_string.is_binary() << '\n'; + std::cout << j_binary.is_binary() << '\n'; +} diff --git a/json-develop/docs/examples/is_binary.output b/json-develop/docs/examples/is_binary.output new file mode 100644 index 0000000..505e76e --- /dev/null +++ b/json-develop/docs/examples/is_binary.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +false +true diff --git a/json-develop/docs/examples/is_boolean.cpp b/json-develop/docs/examples/is_boolean.cpp new file mode 100644 index 0000000..0b79819 --- /dev/null +++ b/json-develop/docs/examples/is_boolean.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_boolean() + std::cout << std::boolalpha; + std::cout << j_null.is_boolean() << '\n'; + std::cout << j_boolean.is_boolean() << '\n'; + std::cout << j_number_integer.is_boolean() << '\n'; + std::cout << j_number_unsigned_integer.is_boolean() << '\n'; + std::cout << j_number_float.is_boolean() << '\n'; + std::cout << j_object.is_boolean() << '\n'; + std::cout << j_array.is_boolean() << '\n'; + std::cout << j_string.is_boolean() << '\n'; + std::cout << j_binary.is_boolean() << '\n'; +} diff --git a/json-develop/docs/examples/is_boolean.output b/json-develop/docs/examples/is_boolean.output new file mode 100644 index 0000000..eace89d --- /dev/null +++ b/json-develop/docs/examples/is_boolean.output @@ -0,0 +1,9 @@ +false +true +false +false +false +false +false +false +false diff --git a/json-develop/docs/examples/is_discarded.cpp b/json-develop/docs/examples/is_discarded.cpp new file mode 100644 index 0000000..0901665 --- /dev/null +++ b/json-develop/docs/examples/is_discarded.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_discarded() + std::cout << std::boolalpha; + std::cout << j_null.is_discarded() << '\n'; + std::cout << j_boolean.is_discarded() << '\n'; + std::cout << j_number_integer.is_discarded() << '\n'; + std::cout << j_number_unsigned_integer.is_discarded() << '\n'; + std::cout << j_number_float.is_discarded() << '\n'; + std::cout << j_object.is_discarded() << '\n'; + std::cout << j_array.is_discarded() << '\n'; + std::cout << j_string.is_discarded() << '\n'; + std::cout << j_binary.is_discarded() << '\n'; +} diff --git a/json-develop/docs/examples/is_discarded.output b/json-develop/docs/examples/is_discarded.output new file mode 100644 index 0000000..14718f6 --- /dev/null +++ b/json-develop/docs/examples/is_discarded.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +false +false diff --git a/json-develop/docs/examples/is_null.cpp b/json-develop/docs/examples/is_null.cpp new file mode 100644 index 0000000..8a84332 --- /dev/null +++ b/json-develop/docs/examples/is_null.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_null() + std::cout << std::boolalpha; + std::cout << j_null.is_null() << '\n'; + std::cout << j_boolean.is_null() << '\n'; + std::cout << j_number_integer.is_null() << '\n'; + std::cout << j_number_unsigned_integer.is_null() << '\n'; + std::cout << j_number_float.is_null() << '\n'; + std::cout << j_object.is_null() << '\n'; + std::cout << j_array.is_null() << '\n'; + std::cout << j_string.is_null() << '\n'; + std::cout << j_binary.is_null() << '\n'; +} diff --git a/json-develop/docs/examples/is_null.output b/json-develop/docs/examples/is_null.output new file mode 100644 index 0000000..42bbee2 --- /dev/null +++ b/json-develop/docs/examples/is_null.output @@ -0,0 +1,9 @@ +true +false +false +false +false +false +false +false +false diff --git a/json-develop/docs/examples/is_number.cpp b/json-develop/docs/examples/is_number.cpp new file mode 100644 index 0000000..f107a04 --- /dev/null +++ b/json-develop/docs/examples/is_number.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number() + std::cout << std::boolalpha; + std::cout << j_null.is_number() << '\n'; + std::cout << j_boolean.is_number() << '\n'; + std::cout << j_number_integer.is_number() << '\n'; + std::cout << j_number_unsigned_integer.is_number() << '\n'; + std::cout << j_number_float.is_number() << '\n'; + std::cout << j_object.is_number() << '\n'; + std::cout << j_array.is_number() << '\n'; + std::cout << j_string.is_number() << '\n'; + std::cout << j_binary.is_number() << '\n'; +} diff --git a/json-develop/docs/examples/is_number.output b/json-develop/docs/examples/is_number.output new file mode 100644 index 0000000..53ef340 --- /dev/null +++ b/json-develop/docs/examples/is_number.output @@ -0,0 +1,9 @@ +false +false +true +true +true +false +false +false +false diff --git a/json-develop/docs/examples/is_number_float.cpp b/json-develop/docs/examples/is_number_float.cpp new file mode 100644 index 0000000..bba2b44 --- /dev/null +++ b/json-develop/docs/examples/is_number_float.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number_float() + std::cout << std::boolalpha; + std::cout << j_null.is_number_float() << '\n'; + std::cout << j_boolean.is_number_float() << '\n'; + std::cout << j_number_integer.is_number_float() << '\n'; + std::cout << j_number_unsigned_integer.is_number_float() << '\n'; + std::cout << j_number_float.is_number_float() << '\n'; + std::cout << j_object.is_number_float() << '\n'; + std::cout << j_array.is_number_float() << '\n'; + std::cout << j_string.is_number_float() << '\n'; + std::cout << j_binary.is_number_float() << '\n'; +} diff --git a/json-develop/docs/examples/is_number_float.output b/json-develop/docs/examples/is_number_float.output new file mode 100644 index 0000000..0e64601 --- /dev/null +++ b/json-develop/docs/examples/is_number_float.output @@ -0,0 +1,9 @@ +false +false +false +false +true +false +false +false +false diff --git a/json-develop/docs/examples/is_number_integer.cpp b/json-develop/docs/examples/is_number_integer.cpp new file mode 100644 index 0000000..8d6a5ae --- /dev/null +++ b/json-develop/docs/examples/is_number_integer.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number_integer() + std::cout << std::boolalpha; + std::cout << j_null.is_number_integer() << '\n'; + std::cout << j_boolean.is_number_integer() << '\n'; + std::cout << j_number_integer.is_number_integer() << '\n'; + std::cout << j_number_unsigned_integer.is_number_integer() << '\n'; + std::cout << j_number_float.is_number_integer() << '\n'; + std::cout << j_object.is_number_integer() << '\n'; + std::cout << j_array.is_number_integer() << '\n'; + std::cout << j_string.is_number_integer() << '\n'; + std::cout << j_binary.is_number_integer() << '\n'; +} diff --git a/json-develop/docs/examples/is_number_integer.output b/json-develop/docs/examples/is_number_integer.output new file mode 100644 index 0000000..c1df310 --- /dev/null +++ b/json-develop/docs/examples/is_number_integer.output @@ -0,0 +1,9 @@ +false +false +true +true +false +false +false +false +false diff --git a/json-develop/docs/examples/is_number_unsigned.cpp b/json-develop/docs/examples/is_number_unsigned.cpp new file mode 100644 index 0000000..b52ac6b --- /dev/null +++ b/json-develop/docs/examples/is_number_unsigned.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number_unsigned() + std::cout << std::boolalpha; + std::cout << j_null.is_number_unsigned() << '\n'; + std::cout << j_boolean.is_number_unsigned() << '\n'; + std::cout << j_number_integer.is_number_unsigned() << '\n'; + std::cout << j_number_unsigned_integer.is_number_unsigned() << '\n'; + std::cout << j_number_float.is_number_unsigned() << '\n'; + std::cout << j_object.is_number_unsigned() << '\n'; + std::cout << j_array.is_number_unsigned() << '\n'; + std::cout << j_string.is_number_unsigned() << '\n'; + std::cout << j_binary.is_number_unsigned() << '\n'; +} diff --git a/json-develop/docs/examples/is_number_unsigned.output b/json-develop/docs/examples/is_number_unsigned.output new file mode 100644 index 0000000..e6059d4 --- /dev/null +++ b/json-develop/docs/examples/is_number_unsigned.output @@ -0,0 +1,9 @@ +false +false +false +true +false +false +false +false +false diff --git a/json-develop/docs/examples/is_object.cpp b/json-develop/docs/examples/is_object.cpp new file mode 100644 index 0000000..a0216fd --- /dev/null +++ b/json-develop/docs/examples/is_object.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_object() + std::cout << std::boolalpha; + std::cout << j_null.is_object() << '\n'; + std::cout << j_boolean.is_object() << '\n'; + std::cout << j_number_integer.is_object() << '\n'; + std::cout << j_number_unsigned_integer.is_object() << '\n'; + std::cout << j_number_float.is_object() << '\n'; + std::cout << j_object.is_object() << '\n'; + std::cout << j_array.is_object() << '\n'; + std::cout << j_string.is_object() << '\n'; + std::cout << j_binary.is_object() << '\n'; +} diff --git a/json-develop/docs/examples/is_object.output b/json-develop/docs/examples/is_object.output new file mode 100644 index 0000000..d9a429f --- /dev/null +++ b/json-develop/docs/examples/is_object.output @@ -0,0 +1,9 @@ +false +false +false +false +false +true +false +false +false diff --git a/json-develop/docs/examples/is_primitive.cpp b/json-develop/docs/examples/is_primitive.cpp new file mode 100644 index 0000000..af3968e --- /dev/null +++ b/json-develop/docs/examples/is_primitive.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_primitive() + std::cout << std::boolalpha; + std::cout << j_null.is_primitive() << '\n'; + std::cout << j_boolean.is_primitive() << '\n'; + std::cout << j_number_integer.is_primitive() << '\n'; + std::cout << j_number_unsigned_integer.is_primitive() << '\n'; + std::cout << j_number_float.is_primitive() << '\n'; + std::cout << j_object.is_primitive() << '\n'; + std::cout << j_array.is_primitive() << '\n'; + std::cout << j_string.is_primitive() << '\n'; + std::cout << j_binary.is_primitive() << '\n'; +} diff --git a/json-develop/docs/examples/is_primitive.output b/json-develop/docs/examples/is_primitive.output new file mode 100644 index 0000000..77af24c --- /dev/null +++ b/json-develop/docs/examples/is_primitive.output @@ -0,0 +1,9 @@ +true +true +true +true +true +false +false +true +true diff --git a/json-develop/docs/examples/is_string.cpp b/json-develop/docs/examples/is_string.cpp new file mode 100644 index 0000000..c89f550 --- /dev/null +++ b/json-develop/docs/examples/is_string.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_string() + std::cout << std::boolalpha; + std::cout << j_null.is_string() << '\n'; + std::cout << j_boolean.is_string() << '\n'; + std::cout << j_number_integer.is_string() << '\n'; + std::cout << j_number_unsigned_integer.is_string() << '\n'; + std::cout << j_number_float.is_string() << '\n'; + std::cout << j_object.is_string() << '\n'; + std::cout << j_array.is_string() << '\n'; + std::cout << j_string.is_string() << '\n'; + std::cout << j_binary.is_string() << '\n'; +} diff --git a/json-develop/docs/examples/is_string.output b/json-develop/docs/examples/is_string.output new file mode 100644 index 0000000..6446f18 --- /dev/null +++ b/json-develop/docs/examples/is_string.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +true +false diff --git a/json-develop/docs/examples/is_structured.cpp b/json-develop/docs/examples/is_structured.cpp new file mode 100644 index 0000000..41947b1 --- /dev/null +++ b/json-develop/docs/examples/is_structured.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_structured() + std::cout << std::boolalpha; + std::cout << j_null.is_structured() << '\n'; + std::cout << j_boolean.is_structured() << '\n'; + std::cout << j_number_integer.is_structured() << '\n'; + std::cout << j_number_unsigned_integer.is_structured() << '\n'; + std::cout << j_number_float.is_structured() << '\n'; + std::cout << j_object.is_structured() << '\n'; + std::cout << j_array.is_structured() << '\n'; + std::cout << j_string.is_structured() << '\n'; + std::cout << j_binary.is_structured() << '\n'; +} diff --git a/json-develop/docs/examples/is_structured.output b/json-develop/docs/examples/is_structured.output new file mode 100644 index 0000000..625c124 --- /dev/null +++ b/json-develop/docs/examples/is_structured.output @@ -0,0 +1,9 @@ +false +false +false +false +false +true +true +false +false diff --git a/json-develop/docs/examples/items.cpp b/json-develop/docs/examples/items.cpp new file mode 100644 index 0000000..9cd2b51 --- /dev/null +++ b/json-develop/docs/examples/items.cpp @@ -0,0 +1,23 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + + // example for an object + for (auto& x : j_object.items()) + { + std::cout << "key: " << x.key() << ", value: " << x.value() << '\n'; + } + + // example for an array + for (auto& x : j_array.items()) + { + std::cout << "key: " << x.key() << ", value: " << x.value() << '\n'; + } +} diff --git a/json-develop/docs/examples/items.output b/json-develop/docs/examples/items.output new file mode 100644 index 0000000..89b09f5 --- /dev/null +++ b/json-develop/docs/examples/items.output @@ -0,0 +1,7 @@ +key: one, value: 1 +key: two, value: 2 +key: 0, value: 1 +key: 1, value: 2 +key: 2, value: 4 +key: 3, value: 8 +key: 4, value: 16 diff --git a/json-develop/docs/examples/json_base_class_t.cpp b/json-develop/docs/examples/json_base_class_t.cpp new file mode 100644 index 0000000..d993522 --- /dev/null +++ b/json-develop/docs/examples/json_base_class_t.cpp @@ -0,0 +1,88 @@ +#include +#include + +class visitor_adaptor_with_metadata +{ + public: + template + void visit(const Fnc& fnc) const; + + int metadata = 42; + private: + template + void do_visit(const Ptr& ptr, const Fnc& fnc) const; +}; + +using json = nlohmann::basic_json < + std::map, + std::vector, + std::string, + bool, + std::int64_t, + std::uint64_t, + double, + std::allocator, + nlohmann::adl_serializer, + std::vector, + visitor_adaptor_with_metadata + >; + +template +void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const +{ + do_visit(json::json_pointer{}, fnc); +} + +template +void visitor_adaptor_with_metadata::do_visit(const Ptr& ptr, const Fnc& fnc) const +{ + using value_t = nlohmann::detail::value_t; + const json& j = *static_cast(this); + switch (j.type()) + { + case value_t::object: + fnc(ptr, j); + for (const auto& entry : j.items()) + { + entry.value().do_visit(ptr / entry.key(), fnc); + } + break; + case value_t::array: + fnc(ptr, j); + for (std::size_t i = 0; i < j.size(); ++i) + { + j.at(i).do_visit(ptr / std::to_string(i), fnc); + } + break; + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + fnc(ptr, j); + break; + case value_t::discarded: + default: + break; + } +} + +int main() +{ + // create a json object + json j; + j["null"]; + j["object"]["uint"] = 1U; + j["object"].metadata = 21; + + // visit and output + j.visit( + [&](const json::json_pointer & p, + const json & j) + { + std::cout << (p.empty() ? std::string{"/"} : p.to_string()) + << " - metadata = " << j.metadata << " -> " << j.dump() << '\n'; + }); +} diff --git a/json-develop/docs/examples/json_base_class_t.output b/json-develop/docs/examples/json_base_class_t.output new file mode 100644 index 0000000..83ce1f6 --- /dev/null +++ b/json-develop/docs/examples/json_base_class_t.output @@ -0,0 +1,4 @@ +/ - metadata = 42 -> {"null":null,"object":{"uint":1}} +/null - metadata = 42 -> null +/object - metadata = 21 -> {"uint":1} +/object/uint - metadata = 42 -> 1 diff --git a/json-develop/docs/examples/json_lines.cpp b/json-develop/docs/examples/json_lines.cpp new file mode 100644 index 0000000..233c81a --- /dev/null +++ b/json-develop/docs/examples/json_lines.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // JSON Lines (see https://jsonlines.org) + std::stringstream input; + input << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} +{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} +{"name": "May", "wins": []} +{"name": "Deloise", "wins": [["three of a kind", "5♣"]]} +)"; + + std::string line; + while (std::getline(input, line)) + { + std::cout << json::parse(line) << std::endl; + } +} diff --git a/json-develop/docs/examples/json_lines.output b/json-develop/docs/examples/json_lines.output new file mode 100644 index 0000000..1b41224 --- /dev/null +++ b/json-develop/docs/examples/json_lines.output @@ -0,0 +1,4 @@ +{"name":"Gilbert","wins":[["straight","7♣"],["one pair","10♥"]]} +{"name":"Alexa","wins":[["two pair","4♠"],["two pair","9♠"]]} +{"name":"May","wins":[]} +{"name":"Deloise","wins":[["three of a kind","5♣"]]} diff --git a/json-develop/docs/examples/json_pointer.cpp b/json-develop/docs/examples/json_pointer.cpp new file mode 100644 index 0000000..75b9717 --- /dev/null +++ b/json-develop/docs/examples/json_pointer.cpp @@ -0,0 +1,47 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // correct JSON pointers + json::json_pointer p1; + json::json_pointer p2(""); + json::json_pointer p3("/"); + json::json_pointer p4("//"); + json::json_pointer p5("/foo/bar"); + json::json_pointer p6("/foo/bar/-"); + json::json_pointer p7("/foo/~0"); + json::json_pointer p8("/foo/~1"); + + // error: JSON pointer does not begin with a slash + try + { + json::json_pointer p9("foo"); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // error: JSON pointer uses escape symbol ~ not followed by 0 or 1 + try + { + json::json_pointer p10("/foo/~"); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // error: JSON pointer uses escape symbol ~ not followed by 0 or 1 + try + { + json::json_pointer p11("/foo/~3"); + } + catch (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/json_pointer.output b/json-develop/docs/examples/json_pointer.output new file mode 100644 index 0000000..9e027d6 --- /dev/null +++ b/json-develop/docs/examples/json_pointer.output @@ -0,0 +1,3 @@ +[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo' +[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' +[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' diff --git a/json-develop/docs/examples/json_pointer__back.cpp b/json-develop/docs/examples/json_pointer__back.cpp new file mode 100644 index 0000000..dd3b210 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__back.cpp @@ -0,0 +1,15 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1("/foo"); + json::json_pointer ptr2("/foo/0"); + + // call empty() + std::cout << "last reference token of \"" << ptr1 << "\" is \"" << ptr1.back() << "\"\n" + << "last reference token of \"" << ptr2 << "\" is \"" << ptr2.back() << "\"" << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__back.output b/json-develop/docs/examples/json_pointer__back.output new file mode 100644 index 0000000..a89357b --- /dev/null +++ b/json-develop/docs/examples/json_pointer__back.output @@ -0,0 +1,2 @@ +last reference token of "/foo" is "foo" +last reference token of "/foo/0" is "0" diff --git a/json-develop/docs/examples/json_pointer__empty.cpp b/json-develop/docs/examples/json_pointer__empty.cpp new file mode 100644 index 0000000..57257e8 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__empty.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + + // call empty() + std::cout << std::boolalpha + << "\"" << ptr0 << "\": " << ptr0.empty() << '\n' + << "\"" << ptr1 << "\": " << ptr1.empty() << '\n' + << "\"" << ptr2 << "\": " << ptr2.empty() << '\n' + << "\"" << ptr3 << "\": " << ptr3.empty() << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__empty.output b/json-develop/docs/examples/json_pointer__empty.output new file mode 100644 index 0000000..a7ee49c --- /dev/null +++ b/json-develop/docs/examples/json_pointer__empty.output @@ -0,0 +1,4 @@ +"": true +"": true +"/foo": false +"/foo/0": false diff --git a/json-develop/docs/examples/json_pointer__operator__equal.cpp b/json-develop/docs/examples/json_pointer__operator__equal.cpp new file mode 100644 index 0000000..dce6df0 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__equal.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // compare JSON pointers + std::cout << std::boolalpha + << "\"" << ptr0 << "\" == \"" << ptr0 << "\": " << (ptr0 == ptr0) << '\n' + << "\"" << ptr0 << "\" == \"" << ptr1 << "\": " << (ptr0 == ptr1) << '\n' + << "\"" << ptr1 << "\" == \"" << ptr2 << "\": " << (ptr1 == ptr2) << '\n' + << "\"" << ptr2 << "\" == \"" << ptr2 << "\": " << (ptr2 == ptr2) << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__operator__equal.output b/json-develop/docs/examples/json_pointer__operator__equal.output new file mode 100644 index 0000000..9a76125 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__equal.output @@ -0,0 +1,4 @@ +"" == "": true +"" == "": true +"" == "/foo": false +"/foo" == "/foo": true diff --git a/json-develop/docs/examples/json_pointer__operator__equal_stringtype.cpp b/json-develop/docs/examples/json_pointer__operator__equal_stringtype.cpp new file mode 100644 index 0000000..af8ec5a --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__equal_stringtype.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // different strings + std::string str0(""); + std::string str1("/foo"); + std::string str2("bar"); + + // compare JSON pointers and strings + std::cout << std::boolalpha + << "\"" << ptr0 << "\" == \"" << str0 << "\": " << (ptr0 == str0) << '\n' + << "\"" << str0 << "\" == \"" << ptr1 << "\": " << (str0 == ptr1) << '\n' + << "\"" << ptr2 << "\" == \"" << str1 << "\": " << (ptr2 == str1) << std::endl; + + try + { + std::cout << "\"" << str2 << "\" == \"" << ptr2 << "\": " << (str2 == ptr2) << std::endl; + } + catch (const json::parse_error& ex) + { + std::cout << ex.what() << std::endl; + } +} diff --git a/json-develop/docs/examples/json_pointer__operator__equal_stringtype.output b/json-develop/docs/examples/json_pointer__operator__equal_stringtype.output new file mode 100644 index 0000000..7fb299d --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__equal_stringtype.output @@ -0,0 +1,4 @@ +"" == "": true +"" == "": true +"/foo" == "/foo": true +"bar" == "/foo": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar' diff --git a/json-develop/docs/examples/json_pointer__operator__notequal.cpp b/json-develop/docs/examples/json_pointer__operator__notequal.cpp new file mode 100644 index 0000000..9bbdd53 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__notequal.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // compare JSON pointers + std::cout << std::boolalpha + << "\"" << ptr0 << "\" != \"" << ptr0 << "\": " << (ptr0 != ptr0) << '\n' + << "\"" << ptr0 << "\" != \"" << ptr1 << "\": " << (ptr0 != ptr1) << '\n' + << "\"" << ptr1 << "\" != \"" << ptr2 << "\": " << (ptr1 != ptr2) << '\n' + << "\"" << ptr2 << "\" != \"" << ptr2 << "\": " << (ptr2 != ptr2) << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__operator__notequal.output b/json-develop/docs/examples/json_pointer__operator__notequal.output new file mode 100644 index 0000000..de891f0 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__notequal.output @@ -0,0 +1,4 @@ +"" != "": false +"" != "": false +"" != "/foo": true +"/foo" != "/foo": false diff --git a/json-develop/docs/examples/json_pointer__operator__notequal_stringtype.cpp b/json-develop/docs/examples/json_pointer__operator__notequal_stringtype.cpp new file mode 100644 index 0000000..b9b8987 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__notequal_stringtype.cpp @@ -0,0 +1,32 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // different strings + std::string str0(""); + std::string str1("/foo"); + std::string str2("bar"); + + // compare JSON pointers and strings + std::cout << std::boolalpha + << "\"" << ptr0 << "\" != \"" << str0 << "\": " << (ptr0 != str0) << '\n' + << "\"" << str0 << "\" != \"" << ptr1 << "\": " << (str0 != ptr1) << '\n' + << "\"" << ptr2 << "\" != \"" << str1 << "\": " << (ptr2 != str1) << std::endl; + + try + { + std::cout << "\"" << str2 << "\" != \"" << ptr2 << "\": " << (str2 != ptr2) << std::endl; + } + catch (const json::parse_error& ex) + { + std::cout << ex.what() << std::endl; + } +} diff --git a/json-develop/docs/examples/json_pointer__operator__notequal_stringtype.output b/json-develop/docs/examples/json_pointer__operator__notequal_stringtype.output new file mode 100644 index 0000000..61331b7 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator__notequal_stringtype.output @@ -0,0 +1,4 @@ +"" != "": false +"" != "": false +"/foo" != "/foo": false +"bar" != "/foo": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar' diff --git a/json-develop/docs/examples/json_pointer__operator_add.cpp b/json-develop/docs/examples/json_pointer__operator_add.cpp new file mode 100644 index 0000000..14bd745 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator_add.cpp @@ -0,0 +1,23 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON pointer + json::json_pointer ptr("/foo"); + std::cout << "\"" << ptr << "\"\n"; + + // append a JSON Pointer + ptr /= json::json_pointer("/bar/baz"); + std::cout << "\"" << ptr << "\"\n"; + + // append a string + ptr /= "fob"; + std::cout << "\"" << ptr << "\"\n"; + + // append an array index + ptr /= 42; + std::cout << "\"" << ptr << "\"" << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__operator_add.output b/json-develop/docs/examples/json_pointer__operator_add.output new file mode 100644 index 0000000..ae13afe --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator_add.output @@ -0,0 +1,4 @@ +"/foo" +"/foo/bar/baz" +"/foo/bar/baz/fob" +"/foo/bar/baz/fob/42" diff --git a/json-develop/docs/examples/json_pointer__operator_add_binary.cpp b/json-develop/docs/examples/json_pointer__operator_add_binary.cpp new file mode 100644 index 0000000..d26a0d1 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator_add_binary.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON pointer + json::json_pointer ptr("/foo"); + + // append a JSON Pointer + std::cout << "\"" << ptr / json::json_pointer("/bar/baz") << "\"\n"; + + // append a string + std::cout << "\"" << ptr / "fob" << "\"\n"; + + // append an array index + std::cout << "\"" << ptr / 42 << "\"" << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__operator_add_binary.output b/json-develop/docs/examples/json_pointer__operator_add_binary.output new file mode 100644 index 0000000..7536042 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator_add_binary.output @@ -0,0 +1,3 @@ +"/foo/bar/baz" +"/foo/fob" +"/foo/42" diff --git a/json-develop/docs/examples/json_pointer__operator_string_t.cpp b/json-develop/docs/examples/json_pointer__operator_string_t.cpp new file mode 100644 index 0000000..56f2130 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator_string_t.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1("/foo/0"); + json::json_pointer ptr2("/a~1b"); + + // implicit conversion to string + std::string s; + s += ptr1; + s += "\n"; + s += ptr2; + + std::cout << s << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__operator_string_t.output b/json-develop/docs/examples/json_pointer__operator_string_t.output new file mode 100644 index 0000000..ec6aba2 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__operator_string_t.output @@ -0,0 +1,2 @@ +/foo/0 +/a~1b diff --git a/json-develop/docs/examples/json_pointer__parent_pointer.cpp b/json-develop/docs/examples/json_pointer__parent_pointer.cpp new file mode 100644 index 0000000..ef9df45 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__parent_pointer.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + + // call parent_pointer() + std::cout << std::boolalpha + << "parent of \"" << ptr1 << "\" is \"" << ptr1.parent_pointer() << "\"\n" + << "parent of \"" << ptr2 << "\" is \"" << ptr2.parent_pointer() << "\"\n" + << "parent of \"" << ptr3 << "\" is \"" << ptr3.parent_pointer() << "\"" << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__parent_pointer.output b/json-develop/docs/examples/json_pointer__parent_pointer.output new file mode 100644 index 0000000..4cc6f3f --- /dev/null +++ b/json-develop/docs/examples/json_pointer__parent_pointer.output @@ -0,0 +1,3 @@ +parent of "" is "" +parent of "/foo" is "" +parent of "/foo/0" is "/foo" diff --git a/json-develop/docs/examples/json_pointer__pop_back.cpp b/json-develop/docs/examples/json_pointer__pop_back.cpp new file mode 100644 index 0000000..fd077b7 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__pop_back.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr("/foo/bar/baz"); + std::cout << "\"" << ptr << "\"\n"; + + // call pop_back() + ptr.pop_back(); + std::cout << "\"" << ptr << "\"\n"; + + ptr.pop_back(); + std::cout << "\"" << ptr << "\"\n"; + + ptr.pop_back(); + std::cout << "\"" << ptr << "\"\n"; +} diff --git a/json-develop/docs/examples/json_pointer__pop_back.output b/json-develop/docs/examples/json_pointer__pop_back.output new file mode 100644 index 0000000..b0468dc --- /dev/null +++ b/json-develop/docs/examples/json_pointer__pop_back.output @@ -0,0 +1,4 @@ +"/foo/bar/baz" +"/foo/bar" +"/foo" +"" diff --git a/json-develop/docs/examples/json_pointer__push_back.cpp b/json-develop/docs/examples/json_pointer__push_back.cpp new file mode 100644 index 0000000..e6b59a1 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__push_back.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr; + std::cout << "\"" << ptr << "\"\n"; + + // call push_back() + ptr.push_back("foo"); + std::cout << "\"" << ptr << "\"\n"; + + ptr.push_back("0"); + std::cout << "\"" << ptr << "\"\n"; + + ptr.push_back("bar"); + std::cout << "\"" << ptr << "\"\n"; +} diff --git a/json-develop/docs/examples/json_pointer__push_back.output b/json-develop/docs/examples/json_pointer__push_back.output new file mode 100644 index 0000000..92c019c --- /dev/null +++ b/json-develop/docs/examples/json_pointer__push_back.output @@ -0,0 +1,4 @@ +"" +"/foo" +"/foo/0" +"/foo/0/bar" diff --git a/json-develop/docs/examples/json_pointer__string_t.cpp b/json-develop/docs/examples/json_pointer__string_t.cpp new file mode 100644 index 0000000..fbe0f17 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__string_t.cpp @@ -0,0 +1,13 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + json::json_pointer::string_t s = "This is a string."; + + std::cout << s << std::endl; + + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__string_t.output b/json-develop/docs/examples/json_pointer__string_t.output new file mode 100644 index 0000000..d871137 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__string_t.output @@ -0,0 +1,2 @@ +This is a string. +true diff --git a/json-develop/docs/examples/json_pointer__to_string.cpp b/json-develop/docs/examples/json_pointer__to_string.cpp new file mode 100644 index 0000000..31d35a7 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__to_string.cpp @@ -0,0 +1,34 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + json::json_pointer ptr4("/"); + json::json_pointer ptr5("/a~1b"); + json::json_pointer ptr6("/c%d"); + json::json_pointer ptr7("/e^f"); + json::json_pointer ptr8("/g|h"); + json::json_pointer ptr9("/i\\j"); + json::json_pointer ptr10("/k\"l"); + json::json_pointer ptr11("/ "); + json::json_pointer ptr12("/m~0n"); + + std::cout << "\"" << ptr1.to_string() << "\"\n" + << "\"" << ptr2.to_string() << "\"\n" + << "\"" << ptr3.to_string() << "\"\n" + << "\"" << ptr4.to_string() << "\"\n" + << "\"" << ptr5.to_string() << "\"\n" + << "\"" << ptr6.to_string() << "\"\n" + << "\"" << ptr7.to_string() << "\"\n" + << "\"" << ptr8.to_string() << "\"\n" + << "\"" << ptr9.to_string() << "\"\n" + << "\"" << ptr10.to_string() << "\"\n" + << "\"" << ptr11.to_string() << "\"\n" + << "\"" << ptr12.to_string() << "\"" << std::endl; +} diff --git a/json-develop/docs/examples/json_pointer__to_string.output b/json-develop/docs/examples/json_pointer__to_string.output new file mode 100644 index 0000000..3c44135 --- /dev/null +++ b/json-develop/docs/examples/json_pointer__to_string.output @@ -0,0 +1,12 @@ +"" +"/foo" +"/foo/0" +"/" +"/a~1b" +"/c%d" +"/e^f" +"/g|h" +"/i\j" +"/k"l" +"/ " +"/m~0n" diff --git a/json-develop/docs/examples/max_size.cpp b/json-develop/docs/examples/max_size.cpp new file mode 100644 index 0000000..c2ffc54 --- /dev/null +++ b/json-develop/docs/examples/max_size.cpp @@ -0,0 +1,25 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call max_size() + std::cout << j_null.max_size() << '\n'; + std::cout << j_boolean.max_size() << '\n'; + std::cout << j_number_integer.max_size() << '\n'; + std::cout << j_number_float.max_size() << '\n'; + std::cout << j_object.max_size() << '\n'; + std::cout << j_array.max_size() << '\n'; + std::cout << j_string.max_size() << '\n'; +} diff --git a/json-develop/docs/examples/max_size.output b/json-develop/docs/examples/max_size.output new file mode 100644 index 0000000..b8dcb4d --- /dev/null +++ b/json-develop/docs/examples/max_size.output @@ -0,0 +1,7 @@ +0 +1 +1 +1 +115292150460684697 +576460752303423487 +1 diff --git a/json-develop/docs/examples/merge_patch.cpp b/json-develop/docs/examples/merge_patch.cpp new file mode 100644 index 0000000..f3fee1e --- /dev/null +++ b/json-develop/docs/examples/merge_patch.cpp @@ -0,0 +1,41 @@ +#include +#include +#include // for std::setw + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json document = R"({ + "title": "Goodbye!", + "author": { + "givenName": "John", + "familyName": "Doe" + }, + "tags": [ + "example", + "sample" + ], + "content": "This will be unchanged" + })"_json; + + // the patch + json patch = R"({ + "title": "Hello!", + "phoneNumber": "+01-123-456-7890", + "author": { + "familyName": null + }, + "tags": [ + "example" + ] + })"_json; + + // apply the patch + document.merge_patch(patch); + + // output original and patched document + std::cout << std::setw(4) << document << std::endl; +} diff --git a/json-develop/docs/examples/merge_patch.output b/json-develop/docs/examples/merge_patch.output new file mode 100644 index 0000000..96adb7b --- /dev/null +++ b/json-develop/docs/examples/merge_patch.output @@ -0,0 +1,11 @@ +{ + "author": { + "givenName": "John" + }, + "content": "This will be unchanged", + "phoneNumber": "+01-123-456-7890", + "tags": [ + "example" + ], + "title": "Hello!" +} diff --git a/json-develop/docs/examples/meta.cpp b/json-develop/docs/examples/meta.cpp new file mode 100644 index 0000000..a051575 --- /dev/null +++ b/json-develop/docs/examples/meta.cpp @@ -0,0 +1,11 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // call meta() + std::cout << std::setw(4) << json::meta() << '\n'; +} diff --git a/json-develop/docs/examples/meta.output b/json-develop/docs/examples/meta.output new file mode 100644 index 0000000..9ceb5e2 --- /dev/null +++ b/json-develop/docs/examples/meta.output @@ -0,0 +1,17 @@ +{ + "compiler": { + "c++": "201103", + "family": "gcc", + "version": "12.1.0" + }, + "copyright": "(C) 2013-2022 Niels Lohmann", + "name": "JSON for Modern C++", + "platform": "apple", + "url": "https://github.com/nlohmann/json", + "version": { + "major": 3, + "minor": 11, + "patch": 2, + "string": "3.11.2" + } +} diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_explicit.cpp b/json-develop/docs/examples/nlohmann_define_type_intrusive_explicit.cpp new file mode 100644 index 0000000..7d2ba8a --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_explicit.cpp @@ -0,0 +1,60 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + friend void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) + { + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; + } + + friend void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t) + { + nlohmann_json_t.name = nlohmann_json_j.at("name"); + nlohmann_json_t.address = nlohmann_json_j.at("address"); + nlohmann_json_t.age = nlohmann_json_j.at("age"); + } +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_explicit.output b/json-develop/docs/examples/nlohmann_define_type_intrusive_explicit.output new file mode 100644 index 0000000..37f4eb4 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_macro.cpp b/json-develop/docs/examples/nlohmann_define_type_intrusive_macro.cpp new file mode 100644 index 0000000..2977cd4 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_macro.cpp @@ -0,0 +1,48 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age) +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_macro.output b/json-develop/docs/examples/nlohmann_define_type_intrusive_macro.output new file mode 100644 index 0000000..37f4eb4 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp new file mode 100644 index 0000000..7400c47 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp @@ -0,0 +1,55 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + friend void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) + { + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; + } + + friend void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t) + { + person nlohmann_json_default_obj; + nlohmann_json_t.name = nlohmann_json_j.value("name", nlohmann_json_default_obj.name); + nlohmann_json_t.address = nlohmann_json_j.value("address", nlohmann_json_default_obj.address); + nlohmann_json_t.age = nlohmann_json_j.value("age", nlohmann_json_default_obj.age); + } +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.output b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.output new file mode 100644 index 0000000..1a255f6 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_macro.cpp b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_macro.cpp new file mode 100644 index 0000000..851a358 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_macro.cpp @@ -0,0 +1,42 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person, name, address, age) +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_macro.output b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_macro.output new file mode 100644 index 0000000..1a255f6 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_intrusive_with_default_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp new file mode 100644 index 0000000..b71613d --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp @@ -0,0 +1,53 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) +{ + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; +} + +void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t) +{ + nlohmann_json_t.name = nlohmann_json_j.at("name"); + nlohmann_json_t.address = nlohmann_json_j.at("address"); + nlohmann_json_t.age = nlohmann_json_j.at("age"); +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_explicit.output b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_explicit.output new file mode 100644 index 0000000..37f4eb4 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_macro.cpp b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_macro.cpp new file mode 100644 index 0000000..be11a45 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_macro.cpp @@ -0,0 +1,41 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age) +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_macro.output b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_macro.output new file mode 100644 index 0000000..37f4eb4 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp new file mode 100644 index 0000000..6b538d1 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp @@ -0,0 +1,53 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} +}; + +void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) +{ + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; +} + +void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t) +{ + person nlohmann_json_default_obj; + nlohmann_json_t.name = nlohmann_json_j.value("name", nlohmann_json_default_obj.name); + nlohmann_json_t.address = nlohmann_json_j.value("address", nlohmann_json_default_obj.address); + nlohmann_json_t.age = nlohmann_json_j.value("age", nlohmann_json_default_obj.age); +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.output b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.output new file mode 100644 index 0000000..1a255f6 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp new file mode 100644 index 0000000..aa9bc53 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp @@ -0,0 +1,40 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person, name, address, age) +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_macro.output b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_macro.output new file mode 100644 index 0000000..1a255f6 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_define_type_non_intrusive_with_default_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/json-develop/docs/examples/nlohmann_json_namespace.cpp b/json-develop/docs/examples/nlohmann_json_namespace.cpp new file mode 100644 index 0000000..4bad91f --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_namespace.cpp @@ -0,0 +1,14 @@ +#include +#include + +// possible use case: use NLOHMANN_JSON_NAMESPACE instead of nlohmann +using json = NLOHMANN_JSON_NAMESPACE::json; + +// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal +#define Q(x) #x +#define QUOTE(x) Q(x) + +int main() +{ + std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_json_namespace.output b/json-develop/docs/examples/nlohmann_json_namespace.output new file mode 100644 index 0000000..1a1df5a --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_namespace.output @@ -0,0 +1 @@ +nlohmann::json_abi_v3_11_2 diff --git a/json-develop/docs/examples/nlohmann_json_namespace_begin.c++17.cpp b/json-develop/docs/examples/nlohmann_json_namespace_begin.c++17.cpp new file mode 100644 index 0000000..9385d59 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_namespace_begin.c++17.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +// partial specialization (see https://json.nlohmann.me/features/arbitrary_types/) +NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> +{ + static void to_json(json& j, const std::optional& opt) + { + if (opt == std::nullopt) + { + j = nullptr; + } + else + { + j = *opt; + } + } +}; +NLOHMANN_JSON_NAMESPACE_END + +int main() +{ + std::optional o1 = 1; + std::optional o2 = std::nullopt; + + NLOHMANN_JSON_NAMESPACE::json j; + j.push_back(o1); + j.push_back(o2); + std::cout << j << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_json_namespace_begin.c++17.output b/json-develop/docs/examples/nlohmann_json_namespace_begin.c++17.output new file mode 100644 index 0000000..b29d3b9 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_namespace_begin.c++17.output @@ -0,0 +1 @@ +[1,null] diff --git a/json-develop/docs/examples/nlohmann_json_namespace_no_version.cpp b/json-develop/docs/examples/nlohmann_json_namespace_no_version.cpp new file mode 100644 index 0000000..97948dd --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_namespace_no_version.cpp @@ -0,0 +1,13 @@ +#include + +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1 +#include + +// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal +#define Q(x) #x +#define QUOTE(x) Q(x) + +int main() +{ + std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_json_namespace_no_version.output b/json-develop/docs/examples/nlohmann_json_namespace_no_version.output new file mode 100644 index 0000000..1c8f313 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_namespace_no_version.output @@ -0,0 +1 @@ +nlohmann::json_abi diff --git a/json-develop/docs/examples/nlohmann_json_serialize_enum.cpp b/json-develop/docs/examples/nlohmann_json_serialize_enum.cpp new file mode 100644 index 0000000..f9e472c --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_serialize_enum.cpp @@ -0,0 +1,59 @@ +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +enum TaskState +{ + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, +{ + { TS_INVALID, nullptr }, + { TS_STOPPED, "stopped" }, + { TS_RUNNING, "running" }, + { TS_COMPLETED, "completed" } +}) + +enum class Color +{ + red, green, blue, unknown +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Color, +{ + { Color::unknown, "unknown" }, { Color::red, "red" }, + { Color::green, "green" }, { Color::blue, "blue" } +}) +} // namespace ns + +int main() +{ + // serialization + json j_stopped = ns::TS_STOPPED; + json j_red = ns::Color::red; + std::cout << "ns::TS_STOPPED -> " << j_stopped + << ", ns::Color::red -> " << j_red << std::endl; + + // deserialization + json j_running = "running"; + json j_blue = "blue"; + auto running = j_running.get(); + auto blue = j_blue.get(); + std::cout << j_running << " -> " << running + << ", " << j_blue << " -> " << static_cast(blue) << std::endl; + + // deserializing undefined JSON value to enum + // (where the first map entry above is the default) + json j_pi = 3.14; + auto invalid = j_pi.get(); + auto unknown = j_pi.get(); + std::cout << j_pi << " -> " << invalid << ", " + << j_pi << " -> " << static_cast(unknown) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_json_serialize_enum.output b/json-develop/docs/examples/nlohmann_json_serialize_enum.output new file mode 100644 index 0000000..f512563 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_serialize_enum.output @@ -0,0 +1,3 @@ +ns::TS_STOPPED -> "stopped", ns::Color::red -> "red" +"running" -> 1, "blue" -> 2 +3.14 -> -1, 3.14 -> 3 diff --git a/json-develop/docs/examples/nlohmann_json_serialize_enum_2.cpp b/json-develop/docs/examples/nlohmann_json_serialize_enum_2.cpp new file mode 100644 index 0000000..fd27226 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_serialize_enum_2.cpp @@ -0,0 +1,33 @@ +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +enum class Color +{ + red, green, blue, unknown +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Color, +{ + { Color::unknown, "unknown" }, { Color::red, "red" }, + { Color::green, "green" }, { Color::blue, "blue" }, + { Color::red, "rot" } // a second conversion for Color::red +}) +} + +int main() +{ + // serialization + json j_red = ns::Color::red; + std::cout << static_cast(ns::Color::red) << " -> " << j_red << std::endl; + + // deserialization + json j_rot = "rot"; + auto rot = j_rot.get(); + auto red = j_red.get(); + std::cout << j_rot << " -> " << static_cast(rot) << std::endl; + std::cout << j_red << " -> " << static_cast(red) << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_json_serialize_enum_2.output b/json-develop/docs/examples/nlohmann_json_serialize_enum_2.output new file mode 100644 index 0000000..5dec31b --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_serialize_enum_2.output @@ -0,0 +1,3 @@ +0 -> "red" +"rot" -> 0 +"red" -> 0 diff --git a/json-develop/docs/examples/nlohmann_json_version.cpp b/json-develop/docs/examples/nlohmann_json_version.cpp new file mode 100644 index 0000000..ca5f537 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_version.cpp @@ -0,0 +1,12 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << "JSON for Modern C++ version " + << NLOHMANN_JSON_VERSION_MAJOR << "." + << NLOHMANN_JSON_VERSION_MINOR << "." + << NLOHMANN_JSON_VERSION_PATCH << std::endl; +} diff --git a/json-develop/docs/examples/nlohmann_json_version.output b/json-develop/docs/examples/nlohmann_json_version.output new file mode 100644 index 0000000..043b9b2 --- /dev/null +++ b/json-develop/docs/examples/nlohmann_json_version.output @@ -0,0 +1 @@ +JSON for Modern C++ version 3.11.2 diff --git a/json-develop/docs/examples/number_float_t.cpp b/json-develop/docs/examples/number_float_t.cpp new file mode 100644 index 0000000..21211dc --- /dev/null +++ b/json-develop/docs/examples/number_float_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/json-develop/docs/examples/number_float_t.output b/json-develop/docs/examples/number_float_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/number_float_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/number_integer_t.cpp b/json-develop/docs/examples/number_integer_t.cpp new file mode 100644 index 0000000..75ee57b --- /dev/null +++ b/json-develop/docs/examples/number_integer_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/json-develop/docs/examples/number_integer_t.output b/json-develop/docs/examples/number_integer_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/number_integer_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/number_unsigned_t.cpp b/json-develop/docs/examples/number_unsigned_t.cpp new file mode 100644 index 0000000..ff3b86d --- /dev/null +++ b/json-develop/docs/examples/number_unsigned_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/json-develop/docs/examples/number_unsigned_t.output b/json-develop/docs/examples/number_unsigned_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/number_unsigned_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/object.cpp b/json-develop/docs/examples/object.cpp new file mode 100644 index 0000000..733b89b --- /dev/null +++ b/json-develop/docs/examples/object.cpp @@ -0,0 +1,28 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON objects + json j_no_init_list = json::object(); + json j_empty_init_list = json::object({}); + json j_list_of_pairs = json::object({ {"one", 1}, {"two", 2} }); + + // serialize the JSON objects + std::cout << j_no_init_list << '\n'; + std::cout << j_empty_init_list << '\n'; + std::cout << j_list_of_pairs << '\n'; + + // example for an exception + try + { + // can only create an object from a list of pairs + json j_invalid_object = json::object({{ "one", 1, 2 }}); + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/object.output b/json-develop/docs/examples/object.output new file mode 100644 index 0000000..1a1d814 --- /dev/null +++ b/json-develop/docs/examples/object.output @@ -0,0 +1,4 @@ +{} +{} +{"one":1,"two":2} +[json.exception.type_error.301] cannot create object from initializer list diff --git a/json-develop/docs/examples/object_comparator_t.cpp b/json-develop/docs/examples/object_comparator_t.cpp new file mode 100644 index 0000000..6b82c7c --- /dev/null +++ b/json-develop/docs/examples/object_comparator_t.cpp @@ -0,0 +1,11 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha + << "json::object_comparator_t(\"one\", \"two\") = " << json::object_comparator_t{}("one", "two") << "\n" + << "json::object_comparator_t(\"three\", \"four\") = " << json::object_comparator_t{}("three", "four") << std::endl; +} diff --git a/json-develop/docs/examples/object_comparator_t.output b/json-develop/docs/examples/object_comparator_t.output new file mode 100644 index 0000000..63620ed --- /dev/null +++ b/json-develop/docs/examples/object_comparator_t.output @@ -0,0 +1,2 @@ +json::object_comparator_t("one", "two") = true +json::object_comparator_t("three", "four") = false diff --git a/json-develop/docs/examples/object_t.cpp b/json-develop/docs/examples/object_t.cpp new file mode 100644 index 0000000..85cfa3e --- /dev/null +++ b/json-develop/docs/examples/object_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same, json::object_t>::value << std::endl; +} diff --git a/json-develop/docs/examples/object_t.output b/json-develop/docs/examples/object_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/object_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/operator__ValueType.cpp b/json-develop/docs/examples/operator__ValueType.cpp new file mode 100644 index 0000000..66fcf31 --- /dev/null +++ b/json-develop/docs/examples/operator__ValueType.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + // use implicit conversions + bool v1 = json_types["boolean"]; + int v2 = json_types["number"]["integer"]; + short v3 = json_types["number"]["integer"]; + float v4 = json_types["number"]["floating-point"]; + int v5 = json_types["number"]["floating-point"]; + std::string v6 = json_types["string"]; + std::vector v7 = json_types["array"]; + std::unordered_map v8 = json_types; + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } + + // example for an exception + try + { + bool v1 = json_types["string"]; + } + catch (json::type_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/json-develop/docs/examples/operator__ValueType.output b/json-develop/docs/examples/operator__ValueType.output new file mode 100644 index 0000000..a3bd9ff --- /dev/null +++ b/json-develop/docs/examples/operator__ValueType.output @@ -0,0 +1,12 @@ +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] +[json.exception.type_error.302] type must be boolean, but is string diff --git a/json-develop/docs/examples/operator__equal.cpp b/json-develop/docs/examples/operator__equal.cpp new file mode 100644 index 0000000..1426f48 --- /dev/null +++ b/json-develop/docs/examples/operator__equal.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.000000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 == array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 == object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 == number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 == string_2) << '\n'; +} diff --git a/json-develop/docs/examples/operator__equal.output b/json-develop/docs/examples/operator__equal.output new file mode 100644 index 0000000..7806735 --- /dev/null +++ b/json-develop/docs/examples/operator__equal.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] false +{"A":"a","B":"b"} == {"A":"a","B":"b"} true +17 == 17.0 true +"foo" == "bar" false diff --git a/json-develop/docs/examples/operator__equal__nullptr_t.cpp b/json-develop/docs/examples/operator__equal__nullptr_t.cpp new file mode 100644 index 0000000..dbb2103 --- /dev/null +++ b/json-develop/docs/examples/operator__equal__nullptr_t.cpp @@ -0,0 +1,22 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array = {1, 2, 3}; + json object = {{"A", "a"}, {"B", "b"}}; + json number = 17; + json string = "foo"; + json null; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array << " == nullptr " << (array == nullptr) << '\n'; + std::cout << object << " == nullptr " << (object == nullptr) << '\n'; + std::cout << number << " == nullptr " << (number == nullptr) << '\n'; + std::cout << string << " == nullptr " << (string == nullptr) << '\n'; + std::cout << null << " == nullptr " << (null == nullptr) << '\n'; +} diff --git a/json-develop/docs/examples/operator__equal__nullptr_t.output b/json-develop/docs/examples/operator__equal__nullptr_t.output new file mode 100644 index 0000000..b7128e1 --- /dev/null +++ b/json-develop/docs/examples/operator__equal__nullptr_t.output @@ -0,0 +1,5 @@ +[1,2,3] == nullptr false +{"A":"a","B":"b"} == nullptr false +17 == nullptr false +"foo" == nullptr false +null == nullptr true diff --git a/json-develop/docs/examples/operator__equal__specializations.cpp b/json-develop/docs/examples/operator__equal__specializations.cpp new file mode 100644 index 0000000..97d5ece --- /dev/null +++ b/json-develop/docs/examples/operator__equal__specializations.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + nlohmann::json uj1 = {{"version", 1}, {"type", "integer"}}; + nlohmann::json uj2 = {{"type", "integer"}, {"version", 1}}; + + nlohmann::ordered_json oj1 = {{"version", 1}, {"type", "integer"}}; + nlohmann::ordered_json oj2 = {{"type", "integer"}, {"version", 1}}; + + std::cout << std::boolalpha << (uj1 == uj2) << '\n' << (oj1 == oj2) << std::endl; +} diff --git a/json-develop/docs/examples/operator__equal__specializations.output b/json-develop/docs/examples/operator__equal__specializations.output new file mode 100644 index 0000000..da29283 --- /dev/null +++ b/json-develop/docs/examples/operator__equal__specializations.output @@ -0,0 +1,2 @@ +true +false diff --git a/json-develop/docs/examples/operator__greater.cpp b/json-develop/docs/examples/operator__greater.cpp new file mode 100644 index 0000000..65bb9c0 --- /dev/null +++ b/json-develop/docs/examples/operator__greater.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " > " << array_2 << " " << (array_1 > array_2) << '\n'; + std::cout << object_1 << " > " << object_2 << " " << (object_1 > object_2) << '\n'; + std::cout << number_1 << " > " << number_2 << " " << (number_1 > number_2) << '\n'; + std::cout << string_1 << " > " << string_2 << " " << (string_1 > string_2) << '\n'; +} diff --git a/json-develop/docs/examples/operator__greater.output b/json-develop/docs/examples/operator__greater.output new file mode 100644 index 0000000..910c48e --- /dev/null +++ b/json-develop/docs/examples/operator__greater.output @@ -0,0 +1,4 @@ +[1,2,3] > [1,2,4] false +{"A":"a","B":"b"} > {"A":"a","B":"b"} false +17 > 17.0000000000001 false +"foo" > "bar" true diff --git a/json-develop/docs/examples/operator__greaterequal.cpp b/json-develop/docs/examples/operator__greaterequal.cpp new file mode 100644 index 0000000..f8659ee --- /dev/null +++ b/json-develop/docs/examples/operator__greaterequal.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " >= " << array_2 << " " << (array_1 >= array_2) << '\n'; + std::cout << object_1 << " >= " << object_2 << " " << (object_1 >= object_2) << '\n'; + std::cout << number_1 << " >= " << number_2 << " " << (number_1 >= number_2) << '\n'; + std::cout << string_1 << " >= " << string_2 << " " << (string_1 >= string_2) << '\n'; +} diff --git a/json-develop/docs/examples/operator__greaterequal.output b/json-develop/docs/examples/operator__greaterequal.output new file mode 100644 index 0000000..c7b9151 --- /dev/null +++ b/json-develop/docs/examples/operator__greaterequal.output @@ -0,0 +1,4 @@ +[1,2,3] >= [1,2,4] false +{"A":"a","B":"b"} >= {"A":"a","B":"b"} true +17 >= 17.0000000000001 false +"foo" >= "bar" true diff --git a/json-develop/docs/examples/operator__less.cpp b/json-develop/docs/examples/operator__less.cpp new file mode 100644 index 0000000..64209a2 --- /dev/null +++ b/json-develop/docs/examples/operator__less.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 < array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 < object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 < number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 < string_2) << '\n'; +} diff --git a/json-develop/docs/examples/operator__less.output b/json-develop/docs/examples/operator__less.output new file mode 100644 index 0000000..abbbc45 --- /dev/null +++ b/json-develop/docs/examples/operator__less.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] true +{"A":"a","B":"b"} == {"A":"a","B":"b"} false +17 == 17.0000000000001 true +"foo" == "bar" false diff --git a/json-develop/docs/examples/operator__lessequal.cpp b/json-develop/docs/examples/operator__lessequal.cpp new file mode 100644 index 0000000..543b954 --- /dev/null +++ b/json-develop/docs/examples/operator__lessequal.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " <= " << array_2 << " " << (array_1 <= array_2) << '\n'; + std::cout << object_1 << " <= " << object_2 << " " << (object_1 <= object_2) << '\n'; + std::cout << number_1 << " <= " << number_2 << " " << (number_1 <= number_2) << '\n'; + std::cout << string_1 << " <= " << string_2 << " " << (string_1 <= string_2) << '\n'; +} diff --git a/json-develop/docs/examples/operator__lessequal.output b/json-develop/docs/examples/operator__lessequal.output new file mode 100644 index 0000000..f7f0327 --- /dev/null +++ b/json-develop/docs/examples/operator__lessequal.output @@ -0,0 +1,4 @@ +[1,2,3] <= [1,2,4] true +{"A":"a","B":"b"} <= {"A":"a","B":"b"} true +17 <= 17.0000000000001 true +"foo" <= "bar" false diff --git a/json-develop/docs/examples/operator__notequal.cpp b/json-develop/docs/examples/operator__notequal.cpp new file mode 100644 index 0000000..43e8950 --- /dev/null +++ b/json-develop/docs/examples/operator__notequal.cpp @@ -0,0 +1,24 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.000000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " != " << array_2 << " " << (array_1 != array_2) << '\n'; + std::cout << object_1 << " != " << object_2 << " " << (object_1 != object_2) << '\n'; + std::cout << number_1 << " != " << number_2 << " " << (number_1 != number_2) << '\n'; + std::cout << string_1 << " != " << string_2 << " " << (string_1 != string_2) << '\n'; +} diff --git a/json-develop/docs/examples/operator__notequal.output b/json-develop/docs/examples/operator__notequal.output new file mode 100644 index 0000000..6cbc0e8 --- /dev/null +++ b/json-develop/docs/examples/operator__notequal.output @@ -0,0 +1,4 @@ +[1,2,3] != [1,2,4] true +{"A":"a","B":"b"} != {"A":"a","B":"b"} false +17 != 17.0 false +"foo" != "bar" true diff --git a/json-develop/docs/examples/operator__notequal__nullptr_t.cpp b/json-develop/docs/examples/operator__notequal__nullptr_t.cpp new file mode 100644 index 0000000..dc7e6ac --- /dev/null +++ b/json-develop/docs/examples/operator__notequal__nullptr_t.cpp @@ -0,0 +1,22 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array = {1, 2, 3}; + json object = {{"A", "a"}, {"B", "b"}}; + json number = 17; + json string = "foo"; + json null; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array << " != nullptr " << (array != nullptr) << '\n'; + std::cout << object << " != nullptr " << (object != nullptr) << '\n'; + std::cout << number << " != nullptr " << (number != nullptr) << '\n'; + std::cout << string << " != nullptr " << (string != nullptr) << '\n'; + std::cout << null << " != nullptr " << (null != nullptr) << '\n'; +} diff --git a/json-develop/docs/examples/operator__notequal__nullptr_t.output b/json-develop/docs/examples/operator__notequal__nullptr_t.output new file mode 100644 index 0000000..0fc36dc --- /dev/null +++ b/json-develop/docs/examples/operator__notequal__nullptr_t.output @@ -0,0 +1,5 @@ +[1,2,3] != nullptr true +{"A":"a","B":"b"} != nullptr true +17 != nullptr true +"foo" != nullptr true +null != nullptr false diff --git a/json-develop/docs/examples/operator__value_t.cpp b/json-develop/docs/examples/operator__value_t.cpp new file mode 100644 index 0000000..d9aac79 --- /dev/null +++ b/json-develop/docs/examples/operator__value_t.cpp @@ -0,0 +1,38 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call operator value_t() + json::value_t t_null = j_null; + json::value_t t_boolean = j_boolean; + json::value_t t_number_integer = j_number_integer; + json::value_t t_number_unsigned = j_number_unsigned; + json::value_t t_number_float = j_number_float; + json::value_t t_object = j_object; + json::value_t t_array = j_array; + json::value_t t_string = j_string; + + // print types + std::cout << std::boolalpha; + std::cout << (t_null == json::value_t::null) << '\n'; + std::cout << (t_boolean == json::value_t::boolean) << '\n'; + std::cout << (t_number_integer == json::value_t::number_integer) << '\n'; + std::cout << (t_number_unsigned == json::value_t::number_unsigned) << '\n'; + std::cout << (t_number_float == json::value_t::number_float) << '\n'; + std::cout << (t_object == json::value_t::object) << '\n'; + std::cout << (t_array == json::value_t::array) << '\n'; + std::cout << (t_string == json::value_t::string) << '\n'; +} diff --git a/json-develop/docs/examples/operator__value_t.output b/json-develop/docs/examples/operator__value_t.output new file mode 100644 index 0000000..310e632 --- /dev/null +++ b/json-develop/docs/examples/operator__value_t.output @@ -0,0 +1,8 @@ +true +true +true +true +true +true +true +true diff --git a/json-develop/docs/examples/operator_array__json_pointer.cpp b/json-develop/docs/examples/operator_array__json_pointer.cpp new file mode 100644 index 0000000..0fa207f --- /dev/null +++ b/json-develop/docs/examples/operator_array__json_pointer.cpp @@ -0,0 +1,49 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j["/number"_json_pointer] << '\n'; + // output element with JSON pointer "/string" + std::cout << j["/string"_json_pointer] << '\n'; + // output element with JSON pointer "/array" + std::cout << j["/array"_json_pointer] << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j["/array/1"_json_pointer] << '\n'; + + // writing access + + // change the string + j["/string"_json_pointer] = "bar"; + // output the changed string + std::cout << j["string"] << '\n'; + + // "change" a nonexisting object entry + j["/boolean"_json_pointer] = true; + // output the changed object + std::cout << j << '\n'; + + // change an array element + j["/array/1"_json_pointer] = 21; + // "change" an array element with nonexisting index + j["/array/4"_json_pointer] = 44; + // output the changed array + std::cout << j["array"] << '\n'; + + // "change" the array element past the end + j["/array/-"_json_pointer] = 55; + // output the changed array + std::cout << j["array"] << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__json_pointer.output b/json-develop/docs/examples/operator_array__json_pointer.output new file mode 100644 index 0000000..1fd1b03 --- /dev/null +++ b/json-develop/docs/examples/operator_array__json_pointer.output @@ -0,0 +1,8 @@ +1 +"foo" +[1,2] +2 +"bar" +{"array":[1,2],"boolean":true,"number":1,"string":"bar"} +[1,21,null,null,44] +[1,21,null,null,44,55] diff --git a/json-develop/docs/examples/operator_array__json_pointer_const.cpp b/json-develop/docs/examples/operator_array__json_pointer_const.cpp new file mode 100644 index 0000000..f40e249 --- /dev/null +++ b/json-develop/docs/examples/operator_array__json_pointer_const.cpp @@ -0,0 +1,25 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + const json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j["/number"_json_pointer] << '\n'; + // output element with JSON pointer "/string" + std::cout << j["/string"_json_pointer] << '\n'; + // output element with JSON pointer "/array" + std::cout << j["/array"_json_pointer] << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j["/array/1"_json_pointer] << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__json_pointer_const.output b/json-develop/docs/examples/operator_array__json_pointer_const.output new file mode 100644 index 0000000..7b9306b --- /dev/null +++ b/json-develop/docs/examples/operator_array__json_pointer_const.output @@ -0,0 +1,4 @@ +1 +"foo" +[1,2] +2 diff --git a/json-develop/docs/examples/operator_array__keytype.c++17.cpp b/json-develop/docs/examples/operator_array__keytype.c++17.cpp new file mode 100644 index 0000000..7f2b41d --- /dev/null +++ b/json-develop/docs/examples/operator_array__keytype.c++17.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"sv] << "\n\n"; + + // change element with key "three" + object["three"sv] = 3; + + // output changed array + std::cout << std::setw(4) << object << "\n\n"; + + // mention nonexisting key + object["four"sv]; + + // write to nonexisting key + object["five"sv]["really"sv]["nested"sv] = true; + + // output changed object + std::cout << std::setw(4) << object << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__keytype.c++17.output b/json-develop/docs/examples/operator_array__keytype.c++17.output new file mode 100644 index 0000000..b643587 --- /dev/null +++ b/json-develop/docs/examples/operator_array__keytype.c++17.output @@ -0,0 +1,19 @@ +2 + +{ + "one": 1, + "three": 3, + "two": 2 +} + +{ + "five": { + "really": { + "nested": true + } + }, + "four": null, + "one": 1, + "three": 3, + "two": 2 +} diff --git a/json-develop/docs/examples/operator_array__keytype_const.c++17.cpp b/json-develop/docs/examples/operator_array__keytype_const.c++17.cpp new file mode 100644 index 0000000..2cf94f4 --- /dev/null +++ b/json-develop/docs/examples/operator_array__keytype_const.c++17.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + const json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"sv] << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__keytype_const.c++17.output b/json-develop/docs/examples/operator_array__keytype_const.c++17.output new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/json-develop/docs/examples/operator_array__keytype_const.c++17.output @@ -0,0 +1 @@ +2 diff --git a/json-develop/docs/examples/operator_array__object_t_key_type.cpp b/json-develop/docs/examples/operator_array__object_t_key_type.cpp new file mode 100644 index 0000000..f9b7f73 --- /dev/null +++ b/json-develop/docs/examples/operator_array__object_t_key_type.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"] << "\n\n"; + + // change element with key "three" + object["three"] = 3; + + // output changed array + std::cout << std::setw(4) << object << "\n\n"; + + // mention nonexisting key + object["four"]; + + // write to nonexisting key + object["five"]["really"]["nested"] = true; + + // output changed object + std::cout << std::setw(4) << object << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__object_t_key_type.output b/json-develop/docs/examples/operator_array__object_t_key_type.output new file mode 100644 index 0000000..b643587 --- /dev/null +++ b/json-develop/docs/examples/operator_array__object_t_key_type.output @@ -0,0 +1,19 @@ +2 + +{ + "one": 1, + "three": 3, + "two": 2 +} + +{ + "five": { + "really": { + "nested": true + } + }, + "four": null, + "one": 1, + "three": 3, + "two": 2 +} diff --git a/json-develop/docs/examples/operator_array__object_t_key_type_const.cpp b/json-develop/docs/examples/operator_array__object_t_key_type_const.cpp new file mode 100644 index 0000000..1bdb340 --- /dev/null +++ b/json-develop/docs/examples/operator_array__object_t_key_type_const.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + const json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"] << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__object_t_key_type_const.output b/json-develop/docs/examples/operator_array__object_t_key_type_const.output new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/json-develop/docs/examples/operator_array__object_t_key_type_const.output @@ -0,0 +1 @@ +2 diff --git a/json-develop/docs/examples/operator_array__size_type.cpp b/json-develop/docs/examples/operator_array__size_type.cpp new file mode 100644 index 0000000..d6f3e15 --- /dev/null +++ b/json-develop/docs/examples/operator_array__size_type.cpp @@ -0,0 +1,25 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json array = {1, 2, 3, 4, 5}; + + // output element at index 3 (fourth element) + std::cout << array[3] << '\n'; + + // change last element to 6 + array[array.size() - 1] = 6; + + // output changed array + std::cout << array << '\n'; + + // write beyond array limit + array[10] = 11; + + // output changed array + std::cout << array << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__size_type.output b/json-develop/docs/examples/operator_array__size_type.output new file mode 100644 index 0000000..a91a106 --- /dev/null +++ b/json-develop/docs/examples/operator_array__size_type.output @@ -0,0 +1,3 @@ +4 +[1,2,3,4,6] +[1,2,3,4,6,null,null,null,null,null,11] diff --git a/json-develop/docs/examples/operator_array__size_type_const.cpp b/json-develop/docs/examples/operator_array__size_type_const.cpp new file mode 100644 index 0000000..d56fa0a --- /dev/null +++ b/json-develop/docs/examples/operator_array__size_type_const.cpp @@ -0,0 +1,13 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON array + const json array = {"first", "2nd", "third", "fourth"}; + + // output element at index 2 (third element) + std::cout << array.at(2) << '\n'; +} diff --git a/json-develop/docs/examples/operator_array__size_type_const.output b/json-develop/docs/examples/operator_array__size_type_const.output new file mode 100644 index 0000000..4450c9f --- /dev/null +++ b/json-develop/docs/examples/operator_array__size_type_const.output @@ -0,0 +1 @@ +"third" diff --git a/json-develop/docs/examples/operator_deserialize.cpp b/json-develop/docs/examples/operator_deserialize.cpp new file mode 100644 index 0000000..8e3d8bd --- /dev/null +++ b/json-develop/docs/examples/operator_deserialize.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create stream with serialized JSON + std::stringstream ss; + ss << R"({ + "number": 23, + "string": "Hello, world!", + "array": [1, 2, 3, 4, 5], + "boolean": false, + "null": null + })"; + + // create JSON value and read the serialization from the stream + json j; + ss >> j; + + // serialize JSON + std::cout << std::setw(2) << j << '\n'; +} diff --git a/json-develop/docs/examples/operator_deserialize.output b/json-develop/docs/examples/operator_deserialize.output new file mode 100644 index 0000000..81a203f --- /dev/null +++ b/json-develop/docs/examples/operator_deserialize.output @@ -0,0 +1,13 @@ +{ + "array": [ + 1, + 2, + 3, + 4, + 5 + ], + "boolean": false, + "null": null, + "number": 23, + "string": "Hello, world!" +} diff --git a/json-develop/docs/examples/operator_literal_json.cpp b/json-develop/docs/examples/operator_literal_json.cpp new file mode 100644 index 0000000..84ca629 --- /dev/null +++ b/json-develop/docs/examples/operator_literal_json.cpp @@ -0,0 +1,13 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + json j = R"( {"hello": "world", "answer": 42} )"_json; + + std::cout << std::setw(2) << j << '\n'; +} diff --git a/json-develop/docs/examples/operator_literal_json.output b/json-develop/docs/examples/operator_literal_json.output new file mode 100644 index 0000000..6c0a7b3 --- /dev/null +++ b/json-develop/docs/examples/operator_literal_json.output @@ -0,0 +1,4 @@ +{ + "answer": 42, + "hello": "world" +} diff --git a/json-develop/docs/examples/operator_literal_json_pointer.cpp b/json-develop/docs/examples/operator_literal_json_pointer.cpp new file mode 100644 index 0000000..aba93e8 --- /dev/null +++ b/json-develop/docs/examples/operator_literal_json_pointer.cpp @@ -0,0 +1,14 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + json j = R"( {"hello": "world", "answer": 42} )"_json; + auto val = j["/hello"_json_pointer]; + + std::cout << std::setw(2) << val << '\n'; +} diff --git a/json-develop/docs/examples/operator_literal_json_pointer.output b/json-develop/docs/examples/operator_literal_json_pointer.output new file mode 100644 index 0000000..b0fcd34 --- /dev/null +++ b/json-develop/docs/examples/operator_literal_json_pointer.output @@ -0,0 +1 @@ +"world" diff --git a/json-develop/docs/examples/operator_ltlt__basic_json.cpp b/json-develop/docs/examples/operator_ltlt__basic_json.cpp new file mode 100644 index 0000000..3bd4ad5 --- /dev/null +++ b/json-develop/docs/examples/operator_ltlt__basic_json.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + + // serialize without indentation + std::cout << j_object << "\n\n"; + std::cout << j_array << "\n\n"; + + // serialize with indentation + std::cout << std::setw(4) << j_object << "\n\n"; + std::cout << std::setw(2) << j_array << "\n\n"; + std::cout << std::setw(1) << std::setfill('\t') << j_object << "\n\n"; +} diff --git a/json-develop/docs/examples/operator_ltlt__basic_json.output b/json-develop/docs/examples/operator_ltlt__basic_json.output new file mode 100644 index 0000000..7e86bfa --- /dev/null +++ b/json-develop/docs/examples/operator_ltlt__basic_json.output @@ -0,0 +1,22 @@ +{"one":1,"two":2} + +[1,2,4,8,16] + +{ + "one": 1, + "two": 2 +} + +[ + 1, + 2, + 4, + 8, + 16 +] + +{ + "one": 1, + "two": 2 +} + diff --git a/json-develop/docs/examples/operator_ltlt__json_pointer.cpp b/json-develop/docs/examples/operator_ltlt__json_pointer.cpp new file mode 100644 index 0000000..f4fac88 --- /dev/null +++ b/json-develop/docs/examples/operator_ltlt__json_pointer.cpp @@ -0,0 +1,13 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON poiner + json::json_pointer ptr("/foo/bar/baz"); + + // write string representation to stream + std::cout << ptr << std::endl; +} diff --git a/json-develop/docs/examples/operator_ltlt__json_pointer.output b/json-develop/docs/examples/operator_ltlt__json_pointer.output new file mode 100644 index 0000000..ed35943 --- /dev/null +++ b/json-develop/docs/examples/operator_ltlt__json_pointer.output @@ -0,0 +1 @@ +/foo/bar/baz diff --git a/json-develop/docs/examples/operator_spaceship__const_reference.c++20.cpp b/json-develop/docs/examples/operator_spaceship__const_reference.c++20.cpp new file mode 100644 index 0000000..3c6c8b8 --- /dev/null +++ b/json-develop/docs/examples/operator_spaceship__const_reference.c++20.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +using json = nlohmann::json; + +const char* to_string(const std::partial_ordering& po) +{ + if (std::is_lt(po)) + { + return "less"; + } + else if (std::is_gt(po)) + { + return "greater"; + } + else if (std::is_eq(po)) + { + return "equivalent"; + } + return "unordered"; +} + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number = 17; + json string = "foo"; + json discarded = json(json::value_t::discarded); + + + // output values and comparisons + std::cout << array_1 << " <=> " << array_2 << " := " << to_string(array_1 <=> array_2) << '\n'; // *NOPAD* + std::cout << object_1 << " <=> " << object_2 << " := " << to_string(object_1 <=> object_2) << '\n'; // *NOPAD* + std::cout << string << " <=> " << number << " := " << to_string(string <=> number) << '\n'; // *NOPAD* + std::cout << string << " <=> " << discarded << " := " << to_string(string <=> discarded) << '\n'; // *NOPAD* +} diff --git a/json-develop/docs/examples/operator_spaceship__const_reference.c++20.output b/json-develop/docs/examples/operator_spaceship__const_reference.c++20.output new file mode 100644 index 0000000..2e8bf9f --- /dev/null +++ b/json-develop/docs/examples/operator_spaceship__const_reference.c++20.output @@ -0,0 +1,4 @@ +[1,2,3] <=> [1,2,4] := less +{"A":"a","B":"b"} <=> {"A":"a","B":"b"} := equivalent +"foo" <=> 17 := greater +"foo" <=> := unordered diff --git a/json-develop/docs/examples/operator_spaceship__scalartype.c++20.cpp b/json-develop/docs/examples/operator_spaceship__scalartype.c++20.cpp new file mode 100644 index 0000000..d9dc3ca --- /dev/null +++ b/json-develop/docs/examples/operator_spaceship__scalartype.c++20.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +using json = nlohmann::json; + +const char* to_string(const std::partial_ordering& po) +{ + if (std::is_lt(po)) + { + return "less"; + } + else if (std::is_gt(po)) + { + return "greater"; + } + else if (std::is_eq(po)) + { + return "equivalent"; + } + return "unordered"; +} + +int main() +{ + using float_limits = std::numeric_limits; + constexpr auto nan = float_limits::quiet_NaN(); + + // create several JSON values + json boolean = false; + json number = 17; + json string = "17"; + + + // output values and comparisons + std::cout << std::boolalpha << std::fixed; + std::cout << boolean << " <=> " << true << " := " << to_string(boolean <=> true) << '\n'; // *NOPAD* + std::cout << number << " <=> " << 17.0 << " := " << to_string(number <=> 17.0) << '\n'; // *NOPAD* + std::cout << number << " <=> " << nan << " := " << to_string(number <=> nan) << '\n'; // *NOPAD* + std::cout << string << " <=> " << 17 << " := " << to_string(string <=> 17) << '\n'; // *NOPAD* +} diff --git a/json-develop/docs/examples/operator_spaceship__scalartype.c++20.output b/json-develop/docs/examples/operator_spaceship__scalartype.c++20.output new file mode 100644 index 0000000..b2939a5 --- /dev/null +++ b/json-develop/docs/examples/operator_spaceship__scalartype.c++20.output @@ -0,0 +1,4 @@ +false <=> true := less +17 <=> 17.000000 := equivalent +17 <=> nan := unordered +"17" <=> 17 := greater diff --git a/json-develop/docs/examples/ordered_json.cpp b/json-develop/docs/examples/ordered_json.cpp new file mode 100644 index 0000000..effad53 --- /dev/null +++ b/json-develop/docs/examples/ordered_json.cpp @@ -0,0 +1,14 @@ +#include +#include + +using ordered_json = nlohmann::ordered_json; + +int main() +{ + ordered_json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + std::cout << j.dump(2) << '\n'; +} diff --git a/json-develop/docs/examples/ordered_json.output b/json-develop/docs/examples/ordered_json.output new file mode 100644 index 0000000..120cbb2 --- /dev/null +++ b/json-develop/docs/examples/ordered_json.output @@ -0,0 +1,5 @@ +{ + "one": 1, + "two": 2, + "three": 3 +} diff --git a/json-develop/docs/examples/ordered_map.cpp b/json-develop/docs/examples/ordered_map.cpp new file mode 100644 index 0000000..dcc60cb --- /dev/null +++ b/json-develop/docs/examples/ordered_map.cpp @@ -0,0 +1,43 @@ +#include +#include + +// simple output function +template +void output(const char* prefix, const Map& m) +{ + std::cout << prefix << " = { "; + for (auto& element : m) + { + std::cout << element.first << ":" << element.second << ' '; + } + std::cout << "}" << std::endl; +} + +int main() +{ + // create and fill two maps + nlohmann::ordered_map m_ordered; + m_ordered["one"] = "eins"; + m_ordered["two"] = "zwei"; + m_ordered["three"] = "drei"; + + std::map m_std; + m_std["one"] = "eins"; + m_std["two"] = "zwei"; + m_std["three"] = "drei"; + + // output: m_ordered is ordered by insertion order, m_std is ordered by key + output("m_ordered", m_ordered); + output("m_std", m_std); + + // erase and re-add "one" key + m_ordered.erase("one"); + m_ordered["one"] = "eins"; + + m_std.erase("one"); + m_std["one"] = "eins"; + + // output: m_ordered shows newly added key at the end; m_std is again ordered by key + output("m_ordered", m_ordered); + output("m_std", m_std); +} diff --git a/json-develop/docs/examples/ordered_map.output b/json-develop/docs/examples/ordered_map.output new file mode 100644 index 0000000..a4ffc45 --- /dev/null +++ b/json-develop/docs/examples/ordered_map.output @@ -0,0 +1,4 @@ +m_ordered = { one:eins two:zwei three:drei } +m_std = { one:eins three:drei two:zwei } +m_ordered = { two:zwei three:drei one:eins } +m_std = { one:eins three:drei two:zwei } diff --git a/json-develop/docs/examples/other_error.cpp b/json-develop/docs/examples/other_error.cpp new file mode 100644 index 0000000..99c4be7 --- /dev/null +++ b/json-develop/docs/examples/other_error.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + try + { + // executing a failing JSON Patch operation + json value = R"({ + "best_biscuit": { + "name": "Oreo" + } + })"_json; + json patch = R"([{ + "op": "test", + "path": "/best_biscuit/name", + "value": "Choco Leibniz" + }])"_json; + value.patch(patch); + } + catch (json::other_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/json-develop/docs/examples/other_error.output b/json-develop/docs/examples/other_error.output new file mode 100644 index 0000000..b80f1cb --- /dev/null +++ b/json-develop/docs/examples/other_error.output @@ -0,0 +1,2 @@ +message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"} +exception id: 501 diff --git a/json-develop/docs/examples/out_of_range.cpp b/json-develop/docs/examples/out_of_range.cpp new file mode 100644 index 0000000..e711640 --- /dev/null +++ b/json-develop/docs/examples/out_of_range.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling at() for an invalid index + json j = {1, 2, 3, 4}; + j.at(4) = 10; + } + catch (json::out_of_range& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/json-develop/docs/examples/out_of_range.output b/json-develop/docs/examples/out_of_range.output new file mode 100644 index 0000000..29ec76b --- /dev/null +++ b/json-develop/docs/examples/out_of_range.output @@ -0,0 +1,2 @@ +message: [json.exception.out_of_range.401] array index 4 is out of range +exception id: 401 diff --git a/json-develop/docs/examples/parse__allow_exceptions.cpp b/json-develop/docs/examples/parse__allow_exceptions.cpp new file mode 100644 index 0000000..82449a5 --- /dev/null +++ b/json-develop/docs/examples/parse__allow_exceptions.cpp @@ -0,0 +1,36 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // an invalid JSON text + std::string text = R"( + { + "key": "value without closing quotes + } + )"; + + // parse with exceptions + try + { + json j = json::parse(text); + } + catch (json::parse_error& e) + { + std::cout << e.what() << std::endl; + } + + // parse without exceptions + json j = json::parse(text, nullptr, false); + + if (j.is_discarded()) + { + std::cout << "the input is invalid JSON" << std::endl; + } + else + { + std::cout << "the input is valid JSON: " << j << std::endl; + } +} diff --git a/json-develop/docs/examples/parse__allow_exceptions.output b/json-develop/docs/examples/parse__allow_exceptions.output new file mode 100644 index 0000000..d650824 --- /dev/null +++ b/json-develop/docs/examples/parse__allow_exceptions.output @@ -0,0 +1,2 @@ +[json.exception.parse_error.101] parse error at line 4, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \u000A or \n; last read: '"value without closing quotes' +the input is invalid JSON diff --git a/json-develop/docs/examples/parse__array__parser_callback_t.cpp b/json-develop/docs/examples/parse__array__parser_callback_t.cpp new file mode 100644 index 0000000..63f0a0e --- /dev/null +++ b/json-develop/docs/examples/parse__array__parser_callback_t.cpp @@ -0,0 +1,30 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + char text[] = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/json-develop/docs/examples/parse__array__parser_callback_t.output b/json-develop/docs/examples/parse__array__parser_callback_t.output new file mode 100644 index 0000000..62bb858 --- /dev/null +++ b/json-develop/docs/examples/parse__array__parser_callback_t.output @@ -0,0 +1,20 @@ +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + diff --git a/json-develop/docs/examples/parse__contiguouscontainer__parser_callback_t.cpp b/json-develop/docs/examples/parse__contiguouscontainer__parser_callback_t.cpp new file mode 100644 index 0000000..6eb409b --- /dev/null +++ b/json-develop/docs/examples/parse__contiguouscontainer__parser_callback_t.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given as std::vector + std::vector text = {'[', '1', ',', '2', ',', '3', ']', '\0'}; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/json-develop/docs/examples/parse__contiguouscontainer__parser_callback_t.output b/json-develop/docs/examples/parse__contiguouscontainer__parser_callback_t.output new file mode 100644 index 0000000..74633e8 --- /dev/null +++ b/json-develop/docs/examples/parse__contiguouscontainer__parser_callback_t.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/json-develop/docs/examples/parse__istream__parser_callback_t.cpp b/json-develop/docs/examples/parse__istream__parser_callback_t.cpp new file mode 100644 index 0000000..afcaa39 --- /dev/null +++ b/json-develop/docs/examples/parse__istream__parser_callback_t.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // fill a stream with JSON text + std::stringstream ss; + ss << text; + + // parse and serialize JSON + json j_complete = json::parse(ss); + std::cout << std::setw(4) << j_complete << "\n\n"; + + + // define parser callback + json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed) + { + // skip object elements with key "Thumbnail" + if (event == json::parse_event_t::key and parsed == json("Thumbnail")) + { + return false; + } + else + { + return true; + } + }; + + // fill a stream with JSON text + ss.clear(); + ss << text; + + // parse (with callback) and serialize JSON + json j_filtered = json::parse(ss, cb); + std::cout << std::setw(4) << j_filtered << '\n'; +} \ No newline at end of file diff --git a/json-develop/docs/examples/parse__istream__parser_callback_t.output b/json-develop/docs/examples/parse__istream__parser_callback_t.output new file mode 100644 index 0000000..279a7ff --- /dev/null +++ b/json-develop/docs/examples/parse__istream__parser_callback_t.output @@ -0,0 +1,34 @@ +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Title": "View from 15th Floor", + "Width": 800 + } +} diff --git a/json-develop/docs/examples/parse__iterator_pair.cpp b/json-develop/docs/examples/parse__iterator_pair.cpp new file mode 100644 index 0000000..d0c30c1 --- /dev/null +++ b/json-develop/docs/examples/parse__iterator_pair.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given an input with other values + std::vector input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'}; + + // parse and serialize JSON + json j_complete = json::parse(input.begin(), input.begin() + 7); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/json-develop/docs/examples/parse__iterator_pair.link b/json-develop/docs/examples/parse__iterator_pair.link new file mode 100644 index 0000000..f464e54 --- /dev/null +++ b/json-develop/docs/examples/parse__iterator_pair.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/json-develop/docs/examples/parse__iterator_pair.output b/json-develop/docs/examples/parse__iterator_pair.output new file mode 100644 index 0000000..74633e8 --- /dev/null +++ b/json-develop/docs/examples/parse__iterator_pair.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/json-develop/docs/examples/parse__pointers.cpp b/json-develop/docs/examples/parse__pointers.cpp new file mode 100644 index 0000000..a5a16ee --- /dev/null +++ b/json-develop/docs/examples/parse__pointers.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given as string that is not null-terminated + const char* ptr = "[1,2,3]another value"; + + // parse and serialize JSON + json j_complete = json::parse(ptr, ptr + 7); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/json-develop/docs/examples/parse__pointers.link b/json-develop/docs/examples/parse__pointers.link new file mode 100644 index 0000000..9a93ef1 --- /dev/null +++ b/json-develop/docs/examples/parse__pointers.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/json-develop/docs/examples/parse__pointers.output b/json-develop/docs/examples/parse__pointers.output new file mode 100644 index 0000000..74633e8 --- /dev/null +++ b/json-develop/docs/examples/parse__pointers.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/json-develop/docs/examples/parse__string__parser_callback_t.cpp b/json-develop/docs/examples/parse__string__parser_callback_t.cpp new file mode 100644 index 0000000..2ae4410 --- /dev/null +++ b/json-develop/docs/examples/parse__string__parser_callback_t.cpp @@ -0,0 +1,49 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; + + + // define parser callback + json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed) + { + // skip object elements with key "Thumbnail" + if (event == json::parse_event_t::key and parsed == json("Thumbnail")) + { + return false; + } + else + { + return true; + } + }; + + // parse (with callback) and serialize JSON + json j_filtered = json::parse(text, cb); + std::cout << std::setw(4) << j_filtered << '\n'; +} diff --git a/json-develop/docs/examples/parse__string__parser_callback_t.output b/json-develop/docs/examples/parse__string__parser_callback_t.output new file mode 100644 index 0000000..279a7ff --- /dev/null +++ b/json-develop/docs/examples/parse__string__parser_callback_t.output @@ -0,0 +1,34 @@ +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Title": "View from 15th Floor", + "Width": 800 + } +} diff --git a/json-develop/docs/examples/parse_error.cpp b/json-develop/docs/examples/parse_error.cpp new file mode 100644 index 0000000..9b27b58 --- /dev/null +++ b/json-develop/docs/examples/parse_error.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // parsing input with a syntax error + json::parse("[1,2,3,]"); + } + catch (json::parse_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << '\n' + << "byte position of error: " << e.byte << std::endl; + } +} diff --git a/json-develop/docs/examples/parse_error.output b/json-develop/docs/examples/parse_error.output new file mode 100644 index 0000000..fe366ff --- /dev/null +++ b/json-develop/docs/examples/parse_error.output @@ -0,0 +1,3 @@ +message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal +exception id: 101 +byte position of error: 8 diff --git a/json-develop/docs/examples/patch.cpp b/json-develop/docs/examples/patch.cpp new file mode 100644 index 0000000..b7ecb8e --- /dev/null +++ b/json-develop/docs/examples/patch.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the patch + json patch = R"( + [ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} + ] + )"_json; + + // apply the patch + json patched_doc = doc.patch(patch); + + // output original and patched document + std::cout << std::setw(4) << doc << "\n\n" + << std::setw(4) << patched_doc << std::endl; +} diff --git a/json-develop/docs/examples/patch.output b/json-develop/docs/examples/patch.output new file mode 100644 index 0000000..eb558fe --- /dev/null +++ b/json-develop/docs/examples/patch.output @@ -0,0 +1,11 @@ +{ + "baz": "qux", + "foo": "bar" +} + +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/json-develop/docs/examples/patch_inplace.cpp b/json-develop/docs/examples/patch_inplace.cpp new file mode 100644 index 0000000..061708a --- /dev/null +++ b/json-develop/docs/examples/patch_inplace.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the patch + json patch = R"( + [ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} + ] + )"_json; + + // output original document + std::cout << "Before\n" << std::setw(4) << doc << std::endl; + + // apply the patch + doc.patch_inplace(patch); + + // output patched document + std::cout << "\nAfter\n" << std::setw(4) << doc << std::endl; +} diff --git a/json-develop/docs/examples/patch_inplace.output b/json-develop/docs/examples/patch_inplace.output new file mode 100644 index 0000000..9d31b8b --- /dev/null +++ b/json-develop/docs/examples/patch_inplace.output @@ -0,0 +1,13 @@ +Before +{ + "baz": "qux", + "foo": "bar" +} + +After +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/json-develop/docs/examples/push_back.cpp b/json-develop/docs/examples/push_back.cpp new file mode 100644 index 0000000..bbddf4f --- /dev/null +++ b/json-develop/docs/examples/push_back.cpp @@ -0,0 +1,25 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.push_back(6); + array += 7; + null += "first"; + null += "second"; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} diff --git a/json-develop/docs/examples/push_back.output b/json-develop/docs/examples/push_back.output new file mode 100644 index 0000000..3306b60 --- /dev/null +++ b/json-develop/docs/examples/push_back.output @@ -0,0 +1,4 @@ +[1,2,3,4,5] +null +[1,2,3,4,5,6,7] +["first","second"] diff --git a/json-develop/docs/examples/push_back__initializer_list.cpp b/json-develop/docs/examples/push_back__initializer_list.cpp new file mode 100644 index 0000000..e96645f --- /dev/null +++ b/json-develop/docs/examples/push_back__initializer_list.cpp @@ -0,0 +1,27 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values: + object.push_back({"three", 3}); // object is extended + object += {"four", 4}; // object is extended + null.push_back({"five", 5}); // null is converted to array + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // would throw: + //object.push_back({1, 2, 3}); +} diff --git a/json-develop/docs/examples/push_back__initializer_list.output b/json-develop/docs/examples/push_back__initializer_list.output new file mode 100644 index 0000000..668eb25 --- /dev/null +++ b/json-develop/docs/examples/push_back__initializer_list.output @@ -0,0 +1,4 @@ +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +[["five",5]] diff --git a/json-develop/docs/examples/push_back__object_t__value.cpp b/json-develop/docs/examples/push_back__object_t__value.cpp new file mode 100644 index 0000000..5d694e9 --- /dev/null +++ b/json-develop/docs/examples/push_back__object_t__value.cpp @@ -0,0 +1,25 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + object.push_back(json::object_t::value_type("three", 3)); + object += json::object_t::value_type("four", 4); + null += json::object_t::value_type("A", "a"); + null += json::object_t::value_type("B", "b"); + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; +} diff --git a/json-develop/docs/examples/push_back__object_t__value.output b/json-develop/docs/examples/push_back__object_t__value.output new file mode 100644 index 0000000..b8a7d35 --- /dev/null +++ b/json-develop/docs/examples/push_back__object_t__value.output @@ -0,0 +1,4 @@ +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +{"A":"a","B":"b"} diff --git a/json-develop/docs/examples/rbegin.cpp b/json-develop/docs/examples/rbegin.cpp new file mode 100644 index 0000000..239f7a6 --- /dev/null +++ b/json-develop/docs/examples/rbegin.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-beginning + json::reverse_iterator it = array.rbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/rbegin.output b/json-develop/docs/examples/rbegin.output new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/json-develop/docs/examples/rbegin.output @@ -0,0 +1 @@ +5 diff --git a/json-develop/docs/examples/rend.cpp b/json-develop/docs/examples/rend.cpp new file mode 100644 index 0000000..adadbbd --- /dev/null +++ b/json-develop/docs/examples/rend.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-end + json::reverse_iterator it = array.rend(); + + // increment the iterator to point to the first element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/json-develop/docs/examples/rend.output b/json-develop/docs/examples/rend.output new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/json-develop/docs/examples/rend.output @@ -0,0 +1 @@ +1 diff --git a/json-develop/docs/examples/sax_parse.cpp b/json-develop/docs/examples/sax_parse.cpp new file mode 100644 index 0000000..8602687 --- /dev/null +++ b/json-develop/docs/examples/sax_parse.cpp @@ -0,0 +1,131 @@ +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} diff --git a/json-develop/docs/examples/sax_parse.output b/json-develop/docs/examples/sax_parse.output new file mode 100644 index 0000000..dd2fc2f --- /dev/null +++ b/json-develop/docs/examples/sax_parse.output @@ -0,0 +1,37 @@ +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false diff --git a/json-develop/docs/examples/sax_parse__binary.cpp b/json-develop/docs/examples/sax_parse__binary.cpp new file mode 100644 index 0000000..08bc85d --- /dev/null +++ b/json-develop/docs/examples/sax_parse__binary.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // CBOR byte string + std::vector vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}}; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse CBOR + bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} diff --git a/json-develop/docs/examples/sax_parse__binary.output b/json-develop/docs/examples/sax_parse__binary.output new file mode 100644 index 0000000..f880896 --- /dev/null +++ b/json-develop/docs/examples/sax_parse__binary.output @@ -0,0 +1,3 @@ +binary(val=[...]) + +result: true diff --git a/json-develop/docs/examples/size.cpp b/json-develop/docs/examples/size.cpp new file mode 100644 index 0000000..2375483 --- /dev/null +++ b/json-develop/docs/examples/size.cpp @@ -0,0 +1,29 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call size() + std::cout << j_null.size() << '\n'; + std::cout << j_boolean.size() << '\n'; + std::cout << j_number_integer.size() << '\n'; + std::cout << j_number_float.size() << '\n'; + std::cout << j_object.size() << '\n'; + std::cout << j_object_empty.size() << '\n'; + std::cout << j_array.size() << '\n'; + std::cout << j_array_empty.size() << '\n'; + std::cout << j_string.size() << '\n'; +} diff --git a/json-develop/docs/examples/size.output b/json-develop/docs/examples/size.output new file mode 100644 index 0000000..3831387 --- /dev/null +++ b/json-develop/docs/examples/size.output @@ -0,0 +1,9 @@ +0 +1 +1 +1 +2 +0 +5 +0 +1 diff --git a/json-develop/docs/examples/std_hash.cpp b/json-develop/docs/examples/std_hash.cpp new file mode 100644 index 0000000..9721910 --- /dev/null +++ b/json-develop/docs/examples/std_hash.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + std::cout << "hash(null) = " << std::hash {}(json(nullptr)) << '\n' + << "hash(false) = " << std::hash {}(json(false)) << '\n' + << "hash(0) = " << std::hash {}(json(0)) << '\n' + << "hash(0U) = " << std::hash {}(json(0U)) << '\n' + << "hash(\"\") = " << std::hash {}(json("")) << '\n' + << "hash({}) = " << std::hash {}(json::object()) << '\n' + << "hash([]) = " << std::hash {}(json::array()) << '\n' + << "hash({\"hello\": \"world\"}) = " << std::hash {}("{\"hello\": \"world\"}"_json) + << std::endl; +} diff --git a/json-develop/docs/examples/std_hash.output b/json-develop/docs/examples/std_hash.output new file mode 100644 index 0000000..521d2b4 --- /dev/null +++ b/json-develop/docs/examples/std_hash.output @@ -0,0 +1,8 @@ +hash(null) = 2654435769 +hash(false) = 2654436030 +hash(0) = 2654436095 +hash(0U) = 2654436156 +hash("") = 6142509191626859748 +hash({}) = 2654435832 +hash([]) = 2654435899 +hash({"hello": "world"}) = 4469488738203676328 diff --git a/json-develop/docs/examples/std_swap.cpp b/json-develop/docs/examples/std_swap.cpp new file mode 100644 index 0000000..36ab3ce --- /dev/null +++ b/json-develop/docs/examples/std_swap.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j1 = {{"one", 1}, {"two", 2}}; + json j2 = {1, 2, 4, 8, 16}; + + std::cout << "j1 = " << j1 << " | j2 = " << j2 << '\n'; + + // swap values + std::swap(j1, j2); + + std::cout << "j1 = " << j1 << " | j2 = " << j2 << std::endl; +} diff --git a/json-develop/docs/examples/std_swap.output b/json-develop/docs/examples/std_swap.output new file mode 100644 index 0000000..5ae6db7 --- /dev/null +++ b/json-develop/docs/examples/std_swap.output @@ -0,0 +1,2 @@ +j1 = {"one":1,"two":2} | j2 = [1,2,4,8,16] +j1 = [1,2,4,8,16] | j2 = {"one":1,"two":2} diff --git a/json-develop/docs/examples/string_t.cpp b/json-develop/docs/examples/string_t.cpp new file mode 100644 index 0000000..77a9ea4 --- /dev/null +++ b/json-develop/docs/examples/string_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/json-develop/docs/examples/string_t.output b/json-develop/docs/examples/string_t.output new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/json-develop/docs/examples/string_t.output @@ -0,0 +1 @@ +true diff --git a/json-develop/docs/examples/swap__array_t.cpp b/json-develop/docs/examples/swap__array_t.cpp new file mode 100644 index 0000000..2119dd5 --- /dev/null +++ b/json-develop/docs/examples/swap__array_t.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json value = {{"array", {1, 2, 3, 4}}}; + + // create an array_t + json::array_t array = {"Snap", "Crackle", "Pop"}; + + // swap the array stored in the JSON value + value["array"].swap(array); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "array = " << array << '\n'; +} diff --git a/json-develop/docs/examples/swap__array_t.output b/json-develop/docs/examples/swap__array_t.output new file mode 100644 index 0000000..365302c --- /dev/null +++ b/json-develop/docs/examples/swap__array_t.output @@ -0,0 +1,2 @@ +value = {"array":["Snap","Crackle","Pop"]} +array = [1,2,3,4] diff --git a/json-develop/docs/examples/swap__binary_t.cpp b/json-develop/docs/examples/swap__binary_t.cpp new file mode 100644 index 0000000..4b8fc3d --- /dev/null +++ b/json-develop/docs/examples/swap__binary_t.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a binary value + json value = json::binary({1, 2, 3}); + + // create a binary_t + json::binary_t binary = {{4, 5, 6}}; + + // swap the object stored in the JSON value + value.swap(binary); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "binary = " << json(binary) << '\n'; +} diff --git a/json-develop/docs/examples/swap__binary_t.output b/json-develop/docs/examples/swap__binary_t.output new file mode 100644 index 0000000..68cd768 --- /dev/null +++ b/json-develop/docs/examples/swap__binary_t.output @@ -0,0 +1,2 @@ +value = {"bytes":[4,5,6],"subtype":null} +binary = {"bytes":[1,2,3],"subtype":null} diff --git a/json-develop/docs/examples/swap__object_t.cpp b/json-develop/docs/examples/swap__object_t.cpp new file mode 100644 index 0000000..301b558 --- /dev/null +++ b/json-develop/docs/examples/swap__object_t.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json value = { {"translation", {{"one", "eins"}, {"two", "zwei"}}} }; + + // create an object_t + json::object_t object = {{"cow", "Kuh"}, {"dog", "Hund"}}; + + // swap the object stored in the JSON value + value["translation"].swap(object); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "object = " << object << '\n'; +} diff --git a/json-develop/docs/examples/swap__object_t.output b/json-develop/docs/examples/swap__object_t.output new file mode 100644 index 0000000..b5c9791 --- /dev/null +++ b/json-develop/docs/examples/swap__object_t.output @@ -0,0 +1,2 @@ +value = {"translation":{"cow":"Kuh","dog":"Hund"}} +object = {"one":"eins","two":"zwei"} diff --git a/json-develop/docs/examples/swap__reference.cpp b/json-develop/docs/examples/swap__reference.cpp new file mode 100644 index 0000000..34182ad --- /dev/null +++ b/json-develop/docs/examples/swap__reference.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create two JSON values + json j1 = {1, 2, 3, 4, 5}; + json j2 = {{"pi", 3.141592653589793}, {"e", 2.718281828459045}}; + + // swap the values + j1.swap(j2); + + // output the values + std::cout << "j1 = " << j1 << '\n'; + std::cout << "j2 = " << j2 << '\n'; +} diff --git a/json-develop/docs/examples/swap__reference.output b/json-develop/docs/examples/swap__reference.output new file mode 100644 index 0000000..96b07b0 --- /dev/null +++ b/json-develop/docs/examples/swap__reference.output @@ -0,0 +1,2 @@ +j1 = {"e":2.718281828459045,"pi":3.141592653589793} +j2 = [1,2,3,4,5] diff --git a/json-develop/docs/examples/swap__string_t.cpp b/json-develop/docs/examples/swap__string_t.cpp new file mode 100644 index 0000000..b5d5831 --- /dev/null +++ b/json-develop/docs/examples/swap__string_t.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json value = { "the good", "the bad", "the ugly" }; + + // create string_t + json::string_t string = "the fast"; + + // swap the object stored in the JSON value + value[1].swap(string); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "string = " << string << '\n'; +} diff --git a/json-develop/docs/examples/swap__string_t.output b/json-develop/docs/examples/swap__string_t.output new file mode 100644 index 0000000..ae2a097 --- /dev/null +++ b/json-develop/docs/examples/swap__string_t.output @@ -0,0 +1,2 @@ +value = ["the good","the fast","the ugly"] +string = the bad diff --git a/json-develop/docs/examples/to_bjdata.cpp b/json-develop/docs/examples/to_bjdata.cpp new file mode 100644 index 0000000..9b7abac --- /dev/null +++ b/json-develop/docs/examples/to_bjdata.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +// function to print BJData's diagnostic format +void print_byte(uint8_t byte) +{ + if (32 < byte and byte < 128) + { + std::cout << (char)byte; + } + else + { + std::cout << (int)byte; + } +} + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": false})"_json; + + // serialize it to BJData + std::vector v = json::to_bjdata(j); + + // print the vector content + for (auto& byte : v) + { + print_byte(byte); + } + std::cout << std::endl; + + // create an array of numbers + json array = {1, 2, 3, 4, 5, 6, 7, 8}; + + // serialize it to BJData using default representation + std::vector v_array = json::to_bjdata(array); + // serialize it to BJData using size optimization + std::vector v_array_size = json::to_bjdata(array, true); + // serialize it to BJData using type optimization + std::vector v_array_size_and_type = json::to_bjdata(array, true, true); + + // print the vector contents + for (auto& byte : v_array) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size_and_type) + { + print_byte(byte); + } + std::cout << std::endl; +} diff --git a/json-develop/docs/examples/to_bjdata.output b/json-develop/docs/examples/to_bjdata.output new file mode 100644 index 0000000..087980c --- /dev/null +++ b/json-develop/docs/examples/to_bjdata.output @@ -0,0 +1,4 @@ +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 diff --git a/json-develop/docs/examples/to_bson.cpp b/json-develop/docs/examples/to_bson.cpp new file mode 100644 index 0000000..3484b0b --- /dev/null +++ b/json-develop/docs/examples/to_bson.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to BSON + std::vector v = json::to_bson(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} diff --git a/json-develop/docs/examples/to_bson.output b/json-develop/docs/examples/to_bson.output new file mode 100644 index 0000000..379532a --- /dev/null +++ b/json-develop/docs/examples/to_bson.output @@ -0,0 +1 @@ +0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 diff --git a/json-develop/docs/examples/to_cbor.cpp b/json-develop/docs/examples/to_cbor.cpp new file mode 100644 index 0000000..3d5e041 --- /dev/null +++ b/json-develop/docs/examples/to_cbor.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to CBOR + std::vector v = json::to_cbor(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} diff --git a/json-develop/docs/examples/to_cbor.output b/json-develop/docs/examples/to_cbor.output new file mode 100644 index 0000000..02c9ada --- /dev/null +++ b/json-develop/docs/examples/to_cbor.output @@ -0,0 +1 @@ +0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 diff --git a/json-develop/docs/examples/to_json.cpp b/json-develop/docs/examples/to_json.cpp new file mode 100644 index 0000000..1f82a4d --- /dev/null +++ b/json-develop/docs/examples/to_json.cpp @@ -0,0 +1,32 @@ +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person +struct person +{ + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace ns +{ +void to_json(json& j, const person& p) +{ + j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} }; +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + json j = p; + + std::cout << j << std::endl; +} diff --git a/json-develop/docs/examples/to_json.output b/json-develop/docs/examples/to_json.output new file mode 100644 index 0000000..e9c5bf3 --- /dev/null +++ b/json-develop/docs/examples/to_json.output @@ -0,0 +1 @@ +{"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} diff --git a/json-develop/docs/examples/to_msgpack.cpp b/json-develop/docs/examples/to_msgpack.cpp new file mode 100644 index 0000000..b29ae8c --- /dev/null +++ b/json-develop/docs/examples/to_msgpack.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to MessagePack + std::vector v = json::to_msgpack(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} diff --git a/json-develop/docs/examples/to_msgpack.output b/json-develop/docs/examples/to_msgpack.output new file mode 100644 index 0000000..4d6c40a --- /dev/null +++ b/json-develop/docs/examples/to_msgpack.output @@ -0,0 +1 @@ +0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 diff --git a/json-develop/docs/examples/to_string.cpp b/json-develop/docs/examples/to_string.cpp new file mode 100644 index 0000000..ee44283 --- /dev/null +++ b/json-develop/docs/examples/to_string.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; +using std::to_string; + +int main() +{ + // create values + json j = {{"one", 1}, {"two", 2}}; + int i = 42; + + // use ADL to select best to_string function + auto j_str = to_string(j); // calling nlohmann::to_string + auto i_str = to_string(i); // calling std::to_string + + // serialize without indentation + std::cout << j_str << "\n\n" + << i_str << std::endl; +} diff --git a/json-develop/docs/examples/to_string.output b/json-develop/docs/examples/to_string.output new file mode 100644 index 0000000..b261f35 --- /dev/null +++ b/json-develop/docs/examples/to_string.output @@ -0,0 +1,3 @@ +{"one":1,"two":2} + +42 diff --git a/json-develop/docs/examples/to_ubjson.cpp b/json-develop/docs/examples/to_ubjson.cpp new file mode 100644 index 0000000..fd267a8 --- /dev/null +++ b/json-develop/docs/examples/to_ubjson.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +// function to print UBJSON's diagnostic format +void print_byte(uint8_t byte) +{ + if (32 < byte and byte < 128) + { + std::cout << (char)byte; + } + else + { + std::cout << (int)byte; + } +} + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": false})"_json; + + // serialize it to UBJSON + std::vector v = json::to_ubjson(j); + + // print the vector content + for (auto& byte : v) + { + print_byte(byte); + } + std::cout << std::endl; + + // create an array of numbers + json array = {1, 2, 3, 4, 5, 6, 7, 8}; + + // serialize it to UBJSON using default representation + std::vector v_array = json::to_ubjson(array); + // serialize it to UBJSON using size optimization + std::vector v_array_size = json::to_ubjson(array, true); + // serialize it to UBJSON using type optimization + std::vector v_array_size_and_type = json::to_ubjson(array, true, true); + + // print the vector contents + for (auto& byte : v_array) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size_and_type) + { + print_byte(byte); + } + std::cout << std::endl; +} diff --git a/json-develop/docs/examples/to_ubjson.output b/json-develop/docs/examples/to_ubjson.output new file mode 100644 index 0000000..087980c --- /dev/null +++ b/json-develop/docs/examples/to_ubjson.output @@ -0,0 +1,4 @@ +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 diff --git a/json-develop/docs/examples/type.cpp b/json-develop/docs/examples/type.cpp new file mode 100644 index 0000000..68fba3a --- /dev/null +++ b/json-develop/docs/examples/type.cpp @@ -0,0 +1,28 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call type() + std::cout << std::boolalpha; + std::cout << (j_null.type() == json::value_t::null) << '\n'; + std::cout << (j_boolean.type() == json::value_t::boolean) << '\n'; + std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\n'; + std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\n'; + std::cout << (j_number_float.type() == json::value_t::number_float) << '\n'; + std::cout << (j_object.type() == json::value_t::object) << '\n'; + std::cout << (j_array.type() == json::value_t::array) << '\n'; + std::cout << (j_string.type() == json::value_t::string) << '\n'; +} diff --git a/json-develop/docs/examples/type.output b/json-develop/docs/examples/type.output new file mode 100644 index 0000000..310e632 --- /dev/null +++ b/json-develop/docs/examples/type.output @@ -0,0 +1,8 @@ +true +true +true +true +true +true +true +true diff --git a/json-develop/docs/examples/type_error.cpp b/json-develop/docs/examples/type_error.cpp new file mode 100644 index 0000000..d4f18b1 --- /dev/null +++ b/json-develop/docs/examples/type_error.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling push_back() on a string value + json j = "string"; + j.push_back("another string"); + } + catch (json::type_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/json-develop/docs/examples/type_error.output b/json-develop/docs/examples/type_error.output new file mode 100644 index 0000000..1a67339 --- /dev/null +++ b/json-develop/docs/examples/type_error.output @@ -0,0 +1,2 @@ +message: [json.exception.type_error.308] cannot use push_back() with string +exception id: 308 diff --git a/json-develop/docs/examples/type_name.cpp b/json-develop/docs/examples/type_name.cpp new file mode 100644 index 0000000..32d3590 --- /dev/null +++ b/json-develop/docs/examples/type_name.cpp @@ -0,0 +1,27 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call type_name() + std::cout << j_null << " is a " << j_null.type_name() << '\n'; + std::cout << j_boolean << " is a " << j_boolean.type_name() << '\n'; + std::cout << j_number_integer << " is a " << j_number_integer.type_name() << '\n'; + std::cout << j_number_unsigned << " is a " << j_number_unsigned.type_name() << '\n'; + std::cout << j_number_float << " is a " << j_number_float.type_name() << '\n'; + std::cout << j_object << " is an " << j_object.type_name() << '\n'; + std::cout << j_array << " is an " << j_array.type_name() << '\n'; + std::cout << j_string << " is a " << j_string.type_name() << '\n'; +} diff --git a/json-develop/docs/examples/type_name.output b/json-develop/docs/examples/type_name.output new file mode 100644 index 0000000..f394e81 --- /dev/null +++ b/json-develop/docs/examples/type_name.output @@ -0,0 +1,8 @@ +null is a null +true is a boolean +-17 is a number +42 is a number +23.42 is a number +{"one":1,"two":2} is an object +[1,2,4,8,16] is an array +"Hello, world" is a string diff --git a/json-develop/docs/examples/unflatten.cpp b/json-develop/docs/examples/unflatten.cpp new file mode 100644 index 0000000..75fb02d --- /dev/null +++ b/json-develop/docs/examples/unflatten.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value + json j_flattened = + { + {"/answer/everything", 42}, + {"/happy", true}, + {"/list/0", 1}, + {"/list/1", 0}, + {"/list/2", 2}, + {"/name", "Niels"}, + {"/nothing", nullptr}, + {"/object/currency", "USD"}, + {"/object/value", 42.99}, + {"/pi", 3.141} + }; + + // call unflatten() + std::cout << std::setw(4) << j_flattened.unflatten() << '\n'; +} diff --git a/json-develop/docs/examples/unflatten.output b/json-develop/docs/examples/unflatten.output new file mode 100644 index 0000000..ed48385 --- /dev/null +++ b/json-develop/docs/examples/unflatten.output @@ -0,0 +1,18 @@ +{ + "answer": { + "everything": 42 + }, + "happy": true, + "list": [ + 1, + 0, + 2 + ], + "name": "Niels", + "nothing": null, + "object": { + "currency": "USD", + "value": 42.99 + }, + "pi": 3.141 +} diff --git a/json-develop/docs/examples/update.cpp b/json-develop/docs/examples/update.cpp new file mode 100644 index 0000000..ff94b67 --- /dev/null +++ b/json-develop/docs/examples/update.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create two JSON objects + json o1 = R"( {"color": "red", "price": 17.99, "names": {"de": "Flugzeug"}} )"_json; + json o2 = R"( {"color": "blue", "speed": 100, "names": {"en": "plane"}} )"_json; + json o3 = o1; + + // add all keys from o2 to o1 (updating "color", replacing "names") + o1.update(o2); + + // add all keys from o2 to o1 (updating "color", merging "names") + o3.update(o2, true); + + // output updated object o1 and o3 + std::cout << std::setw(2) << o1 << '\n'; + std::cout << std::setw(2) << o3 << '\n'; +} diff --git a/json-develop/docs/examples/update.output b/json-develop/docs/examples/update.output new file mode 100644 index 0000000..c35a745 --- /dev/null +++ b/json-develop/docs/examples/update.output @@ -0,0 +1,17 @@ +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} diff --git a/json-develop/docs/examples/update__range.cpp b/json-develop/docs/examples/update__range.cpp new file mode 100644 index 0000000..5b43850 --- /dev/null +++ b/json-develop/docs/examples/update__range.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create two JSON objects + json o1 = R"( {"color": "red", "price": 17.99, "names": {"de": "Flugzeug"}} )"_json; + json o2 = R"( {"color": "blue", "speed": 100, "names": {"en": "plane"}} )"_json; + json o3 = o1; + + // add all keys from o2 to o1 (updating "color", replacing "names") + o1.update(o2.begin(), o2.end()); + + // add all keys from o2 to o1 (updating "color", merging "names") + o3.update(o2.begin(), o2.end(), true); + + // output updated object o1 and o3 + std::cout << std::setw(2) << o1 << '\n'; + std::cout << std::setw(2) << o3 << '\n'; +} diff --git a/json-develop/docs/examples/update__range.output b/json-develop/docs/examples/update__range.output new file mode 100644 index 0000000..c35a745 --- /dev/null +++ b/json-develop/docs/examples/update__range.output @@ -0,0 +1,17 @@ +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} diff --git a/json-develop/docs/examples/value__json_ptr.cpp b/json-develop/docs/examples/value__json_ptr.cpp new file mode 100644 index 0000000..d866ef0 --- /dev/null +++ b/json-develop/docs/examples/value__json_ptr.cpp @@ -0,0 +1,31 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON object with different entry types + json j = + { + {"integer", 1}, + {"floating", 42.23}, + {"string", "hello world"}, + {"boolean", true}, + {"object", {{"key1", 1}, {"key2", 2}}}, + {"array", {1, 2, 3}} + }; + + // access existing values + int v_integer = j.value("/integer"_json_pointer, 0); + double v_floating = j.value("/floating"_json_pointer, 47.11); + + // access nonexisting values and rely on default value + std::string v_string = j.value("/nonexisting"_json_pointer, "oops"); + bool v_boolean = j.value("/nonexisting"_json_pointer, false); + + // output values + std::cout << std::boolalpha << v_integer << " " << v_floating + << " " << v_string << " " << v_boolean << "\n"; +} diff --git a/json-develop/docs/examples/value__json_ptr.output b/json-develop/docs/examples/value__json_ptr.output new file mode 100644 index 0000000..dfc40e5 --- /dev/null +++ b/json-develop/docs/examples/value__json_ptr.output @@ -0,0 +1 @@ +1 42.23 oops false diff --git a/json-develop/docs/examples/value__keytype.c++17.cpp b/json-develop/docs/examples/value__keytype.c++17.cpp new file mode 100644 index 0000000..1f6ff5c --- /dev/null +++ b/json-develop/docs/examples/value__keytype.c++17.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object with different entry types + json j = + { + {"integer", 1}, + {"floating", 42.23}, + {"string", "hello world"}, + {"boolean", true}, + {"object", {{"key1", 1}, {"key2", 2}}}, + {"array", {1, 2, 3}} + }; + + // access existing values + int v_integer = j.value("integer"sv, 0); + double v_floating = j.value("floating"sv, 47.11); + + // access nonexisting values and rely on default value + std::string v_string = j.value("nonexisting"sv, "oops"); + bool v_boolean = j.value("nonexisting"sv, false); + + // output values + std::cout << std::boolalpha << v_integer << " " << v_floating + << " " << v_string << " " << v_boolean << "\n"; +} diff --git a/json-develop/docs/examples/value__keytype.c++17.output b/json-develop/docs/examples/value__keytype.c++17.output new file mode 100644 index 0000000..dfc40e5 --- /dev/null +++ b/json-develop/docs/examples/value__keytype.c++17.output @@ -0,0 +1 @@ +1 42.23 oops false diff --git a/json-develop/docs/examples/value__object_t_key_type.cpp b/json-develop/docs/examples/value__object_t_key_type.cpp new file mode 100644 index 0000000..9488d30 --- /dev/null +++ b/json-develop/docs/examples/value__object_t_key_type.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object with different entry types + json j = + { + {"integer", 1}, + {"floating", 42.23}, + {"string", "hello world"}, + {"boolean", true}, + {"object", {{"key1", 1}, {"key2", 2}}}, + {"array", {1, 2, 3}} + }; + + // access existing values + int v_integer = j.value("integer", 0); + double v_floating = j.value("floating", 47.11); + + // access nonexisting values and rely on default value + std::string v_string = j.value("nonexisting", "oops"); + bool v_boolean = j.value("nonexisting", false); + + // output values + std::cout << std::boolalpha << v_integer << " " << v_floating + << " " << v_string << " " << v_boolean << "\n"; +} diff --git a/json-develop/docs/examples/value__object_t_key_type.output b/json-develop/docs/examples/value__object_t_key_type.output new file mode 100644 index 0000000..dfc40e5 --- /dev/null +++ b/json-develop/docs/examples/value__object_t_key_type.output @@ -0,0 +1 @@ +1 42.23 oops false diff --git a/json-develop/docs/json.gif b/json-develop/docs/json.gif new file mode 100644 index 0000000..8219866 Binary files /dev/null and b/json-develop/docs/json.gif differ diff --git a/json-develop/docs/mkdocs/Makefile b/json-develop/docs/mkdocs/Makefile new file mode 100644 index 0000000..e4731bf --- /dev/null +++ b/json-develop/docs/mkdocs/Makefile @@ -0,0 +1,37 @@ +# serve the site locally +serve: prepare_files style_check + venv/bin/mkdocs serve + +serve_dirty: prepare_files style_check + venv/bin/mkdocs serve --dirtyreload + +build: prepare_files style_check + venv/bin/mkdocs build + +# create files that are not versioned inside the mkdocs folder (images, examples) +prepare_files: clean + mkdir docs/examples + cp -r ../json.gif docs/images + cp -r ../examples/*.cpp ../examples/*.output docs/examples + +style_check: + @cd docs ; python3 ../scripts/check_structure.py + +# clean subfolders +clean: + rm -fr docs/images/json.gif docs/examples + +# publish site to GitHub pages +publish: prepare_files + venv/bin/mkdocs gh-deploy --clean --force + +# install a Python virtual environment +install_venv: requirements.txt + python3 -mvenv venv + venv/bin/pip install --upgrade pip + venv/bin/pip install wheel + venv/bin/pip install -r requirements.txt + +# uninstall the virtual environment +uninstall_venv: clean + rm -fr venv diff --git a/json-develop/docs/mkdocs/docs/api/adl_serializer/from_json.md b/json-develop/docs/mkdocs/docs/api/adl_serializer/from_json.md new file mode 100644 index 0000000..ba932e9 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/adl_serializer/from_json.md @@ -0,0 +1,73 @@ +# nlohmann::adl_serializer::from_json + +```cpp +// (1) +template +static auto from_json(BasicJsonType && j, TargetType& val) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), val))) +-> decltype(::nlohmann::from_json(std::forward(j), val), void()) + +// (2) +template +static auto from_json(BasicJsonType && j) noexcept( +noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) +-> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) +``` + +This function is usually called by the [`get()`](../basic_json/get.md) function of the [basic_json](../basic_json) +class (either explicitly or via the conversion operators). + +1. This function is chosen for default-constructible value types. +2. This function is chosen for value types which are not default-constructible. + +## Parameters + +`j` (in) +: JSON value to read from + +`val` (out) +: value to write to + +## Return value + +Copy of the JSON value, converted to `ValueType` + +## Examples + +??? example "Example: (1) Default-constructible type" + + The example below shows how a `from_json` function can be implemented for a user-defined type. This function is + called by the `adl_serializer` when `get()` is called. + + ```cpp + --8<-- "examples/from_json__default_constructible.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_json__default_constructible.output" + ``` + +??? example "Example: (2) Non-default-constructible type" + + The example below shows how a `from_json` is implemented as part of a specialization of the `adl_serializer` to + realize the conversion of a non-default-constructible type. + + ```cpp + --8<-- "examples/from_json__non_default_constructible.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_json__non_default_constructible.output" + ``` + +## See also + +- [to_json](to_json.md) + +## Version history + +- Added in version 2.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/adl_serializer/index.md b/json-develop/docs/mkdocs/docs/api/adl_serializer/index.md new file mode 100644 index 0000000..95f35cd --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/adl_serializer/index.md @@ -0,0 +1,35 @@ +# nlohmann::adl_serializer + +```cpp +template +struct adl_serializer; +``` + +Serializer that uses ADL ([Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)) to choose +`to_json`/`from_json` functions from the types' namespaces. + +It is implemented similar to + +```cpp +template +struct adl_serializer { + template + static void to_json(BasicJsonType& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +## Member functions + +- [**from_json**](from_json.md) - convert a JSON value to any value type +- [**to_json**](to_json.md) - convert any value type to a JSON value + +## Version history + +- Added in version 2.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/adl_serializer/to_json.md b/json-develop/docs/mkdocs/docs/api/adl_serializer/to_json.md new file mode 100644 index 0000000..f8419bd --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/adl_serializer/to_json.md @@ -0,0 +1,43 @@ +# nlohmann::adl_serializer::to_json + +```cpp +template +static auto to_json(BasicJsonType& j, TargetType && val) noexcept( + noexcept(::nlohmann::to_json(j, std::forward(val)))) +-> decltype(::nlohmann::to_json(j, std::forward(val)), void()) +``` + +This function is usually called by the constructors of the [basic_json](../basic_json) class. + +## Parameters + +`j` (out) +: JSON value to write to + +`val` (in) +: value to read from + +## Examples + +??? example + + The example below shows how a `to_json` function can be implemented for a user-defined type. This function is called + by the `adl_serializer` when the constructor `basic_json(ns::person)` is called. + + ```cpp + --8<-- "examples/to_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_json.output" + ``` + +## See also + +- [from_json](from_json.md) + +## Version history + +- Added in version 2.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/accept.md b/json-develop/docs/mkdocs/docs/api/basic_json/accept.md new file mode 100644 index 0000000..1c806e8 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/accept.md @@ -0,0 +1,113 @@ +# nlohmann::basic_json::accept + +```cpp +// (1) +template +static bool accept(InputType&& i, + const bool ignore_comments = false); + +// (2) +template +static bool accept(IteratorType first, IteratorType last, + const bool ignore_comments = false); +``` + +Checks whether the input is valid JSON. + +1. Reads from a compatible input. +2. Reads from a pair of character iterators + + The value_type of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted + respectively as UTF-8, UTF-16 and UTF-32. + +Unlike the [`parse`](parse.md) function, this function neither throws an exception in case of invalid JSON input +(i.e., a parse error) nor creates diagnostic information. + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer (must not be null) + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - a `std::string` + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type, for instance. + + - a pair of `std::string::iterator` or `std::vector::iterator` + - a pair of pointers such as `ptr` and `ptr + len` + +## Parameters + +`i` (in) +: Input to parse from. + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to start of character range + +`last` (in) +: iterator to end of character range + +## Return value + +Whether the input is valid JSON. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. + +## Notes + +(1) A UTF-8 byte order mark is silently ignored. + +!!! danger "Runtime assertion" + + The precondition that a passed `#!cpp FILE` pointer must not be null is enforced with a + [runtime assertion](../../features/assertions.md). + +## Examples + +??? example + + The example below demonstrates the `accept()` function reading from a string. + + ```cpp + --8<-- "examples/accept__string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/accept__string.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [operator>>](../operator_gtgt.md) - deserialize from stream + +## Version history + +- Added in version 3.0.0. +- Ignoring comments via `ignore_comments` added in version 3.9.0. + +!!! warning "Deprecation" + + Overload (2) replaces calls to `accept` with a pair of iterators as their first parameter which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp accept({ptr, ptr+len}, ...);` with `#!cpp accept(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/array.md b/json-develop/docs/mkdocs/docs/api/basic_json/array.md new file mode 100644 index 0000000..22b2ee1 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/array.md @@ -0,0 +1,60 @@ +# nlohmann::basic_json::array + +```cpp +static basic_json array(initializer_list_t init = {}); +``` + +Creates a JSON array value from a given initializer list. That is, given a list of values `a, b, c`, creates the JSON +value `#!json [a, b, c]`. If the initializer list is empty, the empty array `#!json []` is created. + +## Parameters + +`init` (in) +: initializer list with JSON values to create an array from (optional) + +## Return value + +JSON array value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of `init`. + +## Notes + +This function is only needed to express two edge cases that cannot be realized with the initializer list constructor +([`basic_json(initializer_list_t, bool, value_t)`](basic_json.md)). These cases are: + +1. creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list + constructor would create an object, taking the first elements as keys +2. creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty + object + +## Examples + +??? example + + The following code shows an example for the `array` function. + + ```cpp + --8<-- "examples/array.cpp" + ``` + + Output: + + ```json + --8<-- "examples/array.output" + ``` + +## See also + +- [`basic_json(initializer_list_t)`](basic_json.md) - create a JSON value from an initializer list +- [`object`](object.md) - create a JSON object value from an initializer list + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/array_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/array_t.md new file mode 100644 index 0000000..dd2b901 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/array_t.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::array_t + +```cpp +using array_t = ArrayType>; +``` + +The type used to store JSON arrays. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: +> An array is an ordered sequence of zero or more values. + +To store objects in C++, a type is defined by the template parameters explained below. + +## Template parameters + +`ArrayType` +: container type to store arrays (e.g., `std::vector` or `std::list`) + +`AllocatorType` +: the allocator to use for objects (e.g., `std::allocator`) + +## Notes + +#### Default type + +With the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default value for +`array_t` is: + +```cpp +std::vector< + basic_json, // value_type + std::allocator // allocator_type +> +``` + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the maximum depth of nesting. + +In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be +introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the +[`max_size`](max_size.md) function of a JSON array. + +#### Storage + +Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type +`#!cpp array_t*` must be dereferenced. + +## Examples + +??? example + + The following code shows that `array_t` is by default, a typedef to `#!cpp std::vector`. + + ```cpp + --8<-- "examples/array_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/array_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/at.md b/json-develop/docs/mkdocs/docs/api/basic_json/at.md new file mode 100644 index 0000000..5e95045 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/at.md @@ -0,0 +1,226 @@ +# nlohmann::basic_json::at + +```cpp +// (1) +reference at(size_type idx); +const_reference at(size_type idx) const; + +// (2) +reference at(const typename object_t::key_type& key); +const_reference at(const typename object_t::key_type& key) const; + +// (3) +template +reference at(KeyType&& key); +template +const_reference at(KeyType&& key) const; + +// (4) +reference at(const json_pointer& ptr); +const_reference at(const json_pointer& ptr) const; +``` + +1. Returns a reference to the array element at specified location `idx`, with bounds checking. +2. Returns a reference to the object element with specified key `key`, with bounds checking. +3. See 2. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. +4. Returns a reference to the element at specified JSON pointer `ptr`, with bounds checking. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`idx` (in) +: index of the element to access + +`key` (in) +: object key of the elements to access + +`ptr` (in) +: JSON pointer to the desired element + +## Return value + +1. reference to the element at index `idx` +2. reference to the element at key `key` +3. reference to the element at key `key` +4. reference to the element pointed to by `ptr` + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the JSON value is not an array; + in this case, calling `at` with an index makes no sense. See example below. + - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if the index `idx` is out of + range of the array; that is, `idx >= size()`. See example below. +2. The function can throw the following exceptions: + - Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the JSON value is not an object; + in this case, calling `at` with a key makes no sense. See example below. + - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if the key `key` is not + stored in the object; that is, `find(key) == end()`. See example below. +3. See 2. +4. The function can throw the following exceptions: + - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed + JSON pointer `ptr` begins with '0'. See example below. + - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed + JSON pointer `ptr` is not a number. See example below. + - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index in the passed + JSON pointer `ptr` is out of range. See example below. + - Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index '-' is used + in the passed JSON pointer `ptr`. As `at` provides checked access (and no elements are implicitly inserted), the + index '-' is always invalid. See example below. + - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if the JSON pointer describes a + key of an object which cannot be found. See example below. + - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if the JSON pointer `ptr` can + not be resolved. See example below. + +## Complexity + +1. Constant. +2. Logarithmic in the size of the container. +3. Logarithmic in the size of the container. +4. Logarithmic in the size of the container. + +## Examples + +??? example "Example: (1) access specified array element with bounds checking" + + The example below shows how array elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__size_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__size_type.output" + ``` + +??? example "Example: (1) access specified array element with bounds checking" + + The example below shows how array elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__size_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__size_type_const.output" + ``` + +??? example "Example: (2) access specified object element with bounds checking" + + The example below shows how object elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__object_t_key_type.output" + ``` + +??? example "Example: (2) access specified object element with bounds checking" + + The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__object_t_key_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__object_t_key_type_const.output" + ``` + +??? example "Example: (3) access specified object element using string_view with bounds checking" + + The example below shows how object elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__keytype.c++17.output" + ``` + +??? example "Example: (3) access specified object element using string_view with bounds checking" + + The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__keytype_const.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__keytype_const.c++17.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer" + + The example below shows how object elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__json_pointer.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer" + + The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__json_pointer_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__json_pointer_const.output" + ``` + +## See also + +- documentation on [checked access](../../features/element_access/checked_access.md) +- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference +- see [`value`](value.md) for access with default value + +## Version history + +1. Added in version 1.0.0. +2. Added in version 1.0.0. +3. Added in version 3.11.0. +4. Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/back.md b/json-develop/docs/mkdocs/docs/api/basic_json/back.md new file mode 100644 index 0000000..1a71528 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/back.md @@ -0,0 +1,65 @@ +# nlohmann::basic_json::back + +```cpp +reference back(); + +const_reference back() const; +``` + +Returns a reference to the last element in the container. For a JSON container `c`, the expression `c.back()` is +equivalent to + +```cpp +auto tmp = c.end(); +--tmp; +return *tmp; +``` + +## Return value + +In case of a structured type (array or object), a reference to the last element is returned. In case of number, string, +boolean, or binary values, a reference to the value is returned. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +If the JSON value is `#!json null`, exception +[`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) is thrown. + +## Complexity + +Constant. + +## Notes + +!!! info "Precondition" + + The array or object must not be empty. Calling `back` on an empty array or object yields undefined behavior. + +## Examples + +??? example + + The following code shows an example for `back()`. + + ```cpp + --8<-- "examples/back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/back.output" + ``` + +## See also + +- [front](front.md) to access the first element + +## Version history + +- Added in version 1.0.0. +- Adjusted code to return reference to binary values in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/basic_json.md b/json-develop/docs/mkdocs/docs/api/basic_json/basic_json.md new file mode 100644 index 0000000..e2e7361 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/basic_json.md @@ -0,0 +1,402 @@ +# nlohmann::basic_json::basic_json + +```cpp +// (1) +basic_json(const value_t v); + +// (2) +basic_json(std::nullptr_t = nullptr) noexcept; + +// (3) +template +basic_json(CompatibleType&& val) noexcept(noexcept( + JSONSerializer::to_json(std::declval(), + std::forward(val)))); + +// (4) +template +basic_json(const BasicJsonType& val); + +// (5) +basic_json(initializer_list_t init, + bool type_deduction = true, + value_t manual_type = value_t::array); + +// (6) +basic_json(size_type cnt, const basic_json& val); + +// (7) +basic_json(iterator first, iterator last); +basic_json(const_iterator first, const_iterator last); + +// (8) +basic_json(const basic_json& other); + +// (9) +basic_json(basic_json&& other) noexcept; +``` + +1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends + on the type: + + | Value type | initial value | + |------------|----------------| + | null | `#!json null` | + | boolean | `#!json false` | + | string | `#!json ""` | + | number | `#!json 0` | + | object | `#!json {}` | + | array | `#!json []` | + | binary | empty array | + + The postcondition of this constructor can be restored by calling [`clear()`](clear.md). + +2. Create a `#!json null` JSON value. It either takes a null pointer as parameter (explicitly creating `#!json null`) + or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read -- it is only used to + choose the right constructor. + +3. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method + exists. The constructor forwards the parameter `val` to that method (to `json_serializer::to_json` method with + `U = uncvref_t`, to be exact). + + Template type `CompatibleType` includes, but is not limited to, the following types: + + - **arrays**: [`array_t`](array_t.md) and all kinds of compatible containers such as `std::vector`, `std::deque`, + `std::list`, `std::forward_list`, `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, `std::multiset`, + and `std::unordered_multiset` with a `value_type` from which a `basic_json` value can be constructed. + - **objects**: [`object_t`](object_t.md) and all kinds of compatible associative containers such as `std::map`, + `std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t` + and a `value_type` from which a `basic_json` value can be constructed. + - **strings**: `string_t`, string literals, and all compatible string containers can be used. + - **numbers**: [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md), + [`number_float_t`](number_float_t.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float` + or `double` can be used. + - **boolean**: `boolean_t` / `bool` can be used. + - **binary**: `binary_t` / `std::vector` may be used; unfortunately because string literals cannot be + distinguished from binary character arrays by the C++ type system, all types compatible with `const char*` will be + directed to the string constructor instead. This is both for backwards compatibility, and due to the fact that a + binary type is not a standard JSON type. + + See the examples below. + +4. This is a constructor for existing `basic_json` types. It does not hijack copy/move constructors, since the parameter + has different template arguments than the current ones. + + The constructor tries to convert the internal `m_value` of the parameter. + +5. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is + `#!cpp true` (default), the type of the JSON value to be created is deducted from the initializer list `init` + according to the following rules: + + 1. If the list is empty, an empty JSON object value `{}` is created. + 2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first + elements of the pairs are treated as keys and the second elements are as values. + 3. In all other cases, an array is created. + + The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows: + + 1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object. + 2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be + of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an + object. + 3. In all other cases, the initializer list could not be interpreted as JSON object type, so interpreting it as JSON + array type is safe. + + With the rules described above, the following JSON values cannot be expressed by an initializer list: + + - the empty array (`#!json []`): use `array(initializer_list_t)` with an empty initializer list in this case + - arrays whose elements satisfy rule 2: use `array(initializer_list_t)` with the same initializer list in this case + + Function [`array()`](array.md) and [`object()`](object.md) force array and object creation from initializer lists, + respectively. + +6. Constructs a JSON array value by creating `cnt` copies of a passed value. In case `cnt` is `0`, an empty array is + created. + +7. Constructs the JSON value with the contents of the range `[first, last)`. The semantics depends on the different + types a JSON value can have: + + - In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206) + is thrown. + - In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be + `end()`. In this case, the value is copied. Otherwise, + [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown. + - In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or + `std::map`; that is, a JSON array or object is constructed from the values in the range. + +8. Creates a copy of a given JSON value. + +9. Move constructor. Constructs a JSON value with the contents of the given value `other` using move semantics. It + "steals" the resources from `other` and leaves it as JSON `#!json null` value. + +## Template parameters + +`CompatibleType` +: a type such that: + + - `CompatibleType` is not derived from `std::istream`, + - `CompatibleType` is not `basic_json` (to avoid hijacking copy/move constructors), + - `CompatibleType` is not a different `basic_json` type (i.e. with different template arguments) + - `CompatibleType` is not a `basic_json` nested type (e.g., `json_pointer`, `iterator`, etc.) + - `json_serializer` (with `U = uncvref_t`) has a `to_json(basic_json_t&, CompatibleType&&)` + method + +`BasicJsonType`: +: a type such that: + + - `BasicJsonType` is a `basic_json` type. + - `BasicJsonType` has different template arguments than `basic_json_t`. + +`U`: +: `uncvref_t` + +## Parameters + +`v` (in) +: the type of the value to create + +`val` (in) +: the value to be forwarded to the respective constructor + +`init` (in) +: initializer list with JSON values + +`type_deduction` (in) +: internal parameter; when set to `#!cpp true`, the type of the JSON value is deducted from the initializer list + `init`; when set to `#!cpp false`, the type provided via `manual_type` is forced. This mode is used by the functions + `array(initializer_list_t)` and `object(initializer_list_t)`. + +`manual_type` (in) +: internal parameter; when `type_deduction` is set to `#!cpp false`, the created JSON value will use the provided type + (only `value_t::array` and `value_t::object` are valid); when `type_deduction` is set to `#!cpp true`, this + parameter has no effect + +`cnt` (in) +: the number of JSON copies of `val` to create + +`first` (in) +: begin of the range to copy from (included) + +`last` (in) +: end of the range to copy from (excluded) + +`other` (in) +: the JSON value to copy/move + +## Exception safety + +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +2. No-throw guarantee: this constructor never throws exceptions. +3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no + `to_json()` function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any + JSON value. +4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no + `to_json()` function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any + JSON value. +5. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +6. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +7. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +9. No-throw guarantee: this constructor never throws exceptions. + +## Exceptions + +1. (none) +2. The function does not throw exceptions. +3. (none) +4. (none) +5. The function can throw the following exceptions: + - Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `type_deduction` is + `#!cpp false`, `manual_type` is `value_t::object`, but `init` contains an element which is not a pair whose first + element is a string. In this case, the constructor could not create an object. If `type_deduction` would have been + `#!cpp true`, an array would have been created. See `object(initializer_list_t)` for an example. +6. (none) +7. The function can throw the following exceptions: + - Throws [`invalid_iterator.201`](../../home/exceptions.md#jsonexceptioninvalid_iterator201) if iterators `first` + and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range + `[first, last)` is undefined. + - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first` + and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first + element anymore. In this case, the range `[first, last)` is undefined. See example code below. + - Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first` + and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined. +8. (none) +9. The function does not throw exceptions. + +## Complexity + +1. Constant. +2. Constant. +3. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()` + method. +4. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()` + method. +5. Linear in the size of the initializer list `init`. +6. Linear in `cnt`. +7. Linear in distance between `first` and `last`. +8. Linear in the size of `other`. +9. Constant. + +## Notes + +- Overload 5: + + !!! note "Empty initializer list" + + When used without parentheses around an empty initializer list, `basic_json()` is called instead of this + function, yielding the JSON `#!json null` value. + +- Overload 7: + + !!! info "Preconditions" + + - Iterators `first` and `last` must be initialized. **This precondition is enforced with a + [runtime assertion](../../features/assertions.md). + - Range `[first, last)` is valid. Usually, this precondition cannot be checked efficiently. Only certain edge + cases are detected; see the description of the exceptions above. A violation of this precondition yields + undefined behavior. + + !!! danger "Runtime assertion" + + A precondition is enforced with a [runtime assertion](../../features/assertions.md). + +- Overload 8: + + !!! info "Postcondition" + + `#!cpp *this == other` + +- Overload 9: + + !!! info "Postconditions" + + - `#!cpp `*this` has the same value as `other` before the call. + - `other` is a JSON `#!json null` value + +## Examples + +??? example "Example: (1) create an empty value with a given type" + + The following code shows the constructor for different `value_t` values. + + ```cpp + --8<-- "examples/basic_json__value_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__value_t.output" + ``` + +??? example "Example: (2) create a `#!json null` object" + + The following code shows the constructor with and without a null pointer parameter. + + ```cpp + --8<-- "examples/basic_json__nullptr_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__nullptr_t.output" + ``` + +??? example "Example: (3) create a JSON value from compatible types" + + The following code shows the constructor with several compatible types. + + ```cpp + --8<-- "examples/basic_json__CompatibleType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__CompatibleType.output" + ``` + + Note the output is platform-dependent. + +??? example "Example: (5) create a container (array or object) from an initializer list" + + The example below shows how JSON values are created from initializer lists. + + ```cpp + --8<-- "examples/basic_json__list_init_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__list_init_t.output" + ``` + +??? example "Example: (6) construct an array with count copies of given value" + + The following code shows examples for creating arrays with several copies of a given value. + + ```cpp + --8<-- "examples/basic_json__size_type_basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__size_type_basic_json.output" + ``` + +??? example "Example: (7) construct a JSON container given an iterator range" + + The example below shows several ways to create JSON values by specifying a subrange with iterators. + + ```cpp + --8<-- "examples/basic_json__InputIt_InputIt.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__InputIt_InputIt.output" + ``` + +??? example "Example: (8) copy constructor" + + The following code shows an example for the copy constructor. + + ```cpp + --8<-- "examples/basic_json__basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__basic_json.output" + ``` + +??? example "Example: (9) move constructor" + + The code below shows the move constructor explicitly called via `std::move`. + + ```cpp + --8<-- "examples/basic_json__moveconstructor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__moveconstructor.output" + ``` + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +3. Since version 2.1.0. +4. Since version 3.2.0. +5. Since version 1.0.0. +6. Since version 1.0.0. +7. Since version 1.0.0. +8. Since version 1.0.0. +9. Since version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/begin.md b/json-develop/docs/mkdocs/docs/api/basic_json/begin.md new file mode 100644 index 0000000..ef623a5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/begin.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::begin + +```cpp +iterator begin() noexcept; +const_iterator begin() const noexcept; +``` + +Returns an iterator to the first element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `begin()`. + + ```cpp + --8<-- "examples/begin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/begin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/binary.md b/json-develop/docs/mkdocs/docs/api/basic_json/binary.md new file mode 100644 index 0000000..ce45d8a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/binary.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::binary + +```cpp +// (1) +static basic_json binary(const typename binary_t::container_type& init); +static basic_json binary(typename binary_t::container_type&& init); + +// (2) +static basic_json binary(const typename binary_t::container_type& init, + std::uint8_t subtype); +static basic_json binary(typename binary_t::container_type&& init, + std::uint8_t subtype); +``` + +1. Creates a JSON binary array value from a given binary container. +2. Creates a JSON binary array value from a given binary container with subtype. + +Binary values are part of various binary formats, such as CBOR, MessagePack, and BSON. This constructor is used to +create a value for serialization to those formats. + +## Parameters + +`init` (in) +: container containing bytes to use as binary type + +`subtype` (in) +: subtype to use in CBOR, MessagePack, and BSON + +## Return value + +JSON binary array value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of `init`; constant for `typename binary_t::container_type&& init` versions. + +## Notes + +Note, this function exists because of the difficulty in correctly specifying the correct template overload in the +standard value ctor, as both JSON arrays and JSON binary arrays are backed with some form of a `std::vector`. Because +JSON binary arrays are a non-standard extension it was decided that it would be best to prevent automatic initialization +of a binary array type, for backwards compatibility and so it does not happen on accident. + +## Examples + +??? example + + The following code shows how to create a binary value. + + ```cpp + --8<-- "examples/binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/binary_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/binary_t.md new file mode 100644 index 0000000..705c92c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/binary_t.md @@ -0,0 +1,89 @@ +# nlohmann::basic_json::binary_t + +```cpp +using binary_t = byte_container_with_subtype; +``` + +This type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type +2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for +compatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values. + +Additionally, as an implementation detail, the subtype of the binary data is carried around as a `std::uint64_t`, which +is compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is +incompatible with each other, and it is up to the user to translate between them). The subtype is added to `BinaryType` +via the helper type [byte_container_with_subtype](../byte_container_with_subtype/index.md). + +[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type as: +> Major type 2: a byte string. The string's length in bytes is represented following the rules for positive integers +> (major type 0). + +[MessagePack's documentation on the bin type +family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) describes this type as: +> Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array. + +[BSON's specifications](http://bsonspec.org/spec.html) describe several binary types; however, this type is intended to +represent the generic binary type which has the description: +> Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and +> tools. + +None of these impose any limitations on the internal representation other than the basic unit of storage be some type of +array whose parts are decomposable into bytes. + +The default representation of this binary format is a `#!cpp std::vector`, which is a very common way to +represent a byte array in modern C++. + +## Template parameters + +`BinaryType` +: container type to store arrays + +## Notes + +#### Default type + +The default values for `BinaryType` is `#!cpp std::vector`. + +#### Storage + +Binary Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of the +type `#!cpp binary_t*` must be dereferenced. + +#### Notes on subtypes + +- CBOR + - Binary values are represented as byte strings. Subtypes are written as tags. + +- MessagePack + - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1, + fixext2, fixext4, fixext8) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is + then added as signed 8-bit integer. + - If no subtype is given, the bin family (bin8, bin16, bin32) is used. + +- BSON + - If a subtype is given, it is used and added as unsigned 8-bit integer. + - If no subtype is given, the generic binary subtype 0x00 is used. + +## Examples + +??? example + + The following code shows that `binary_t` is by default, a typedef to + `#!cpp nlohmann::byte_container_with_subtype>`. + + ```cpp + --8<-- "examples/binary_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/binary_t.output" + ``` + +## See also + +- [byte_container_with_subtype](../byte_container_with_subtype/index.md) + +## Version history + +- Added in version 3.8.0. Changed type of subtype to `std::uint64_t` in version 3.10.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/boolean_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/boolean_t.md new file mode 100644 index 0000000..e3a7830 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/boolean_t.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::boolean_t + +```cpp +using boolean_t = BooleanType; +``` + +The type used to store JSON booleans. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two +literals `#!json true` and `#!json false`. + +To store objects in C++, a type is defined by the template parameter `BooleanType` which chooses the type to use. + +## Notes + +#### Default type + +With the default values for `BooleanType` (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`. + +#### Storage + +Boolean values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `boolean_t` is by default, a typedef to `#!cpp bool`. + + ```cpp + --8<-- "examples/boolean_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/boolean_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/cbegin.md b/json-develop/docs/mkdocs/docs/api/basic_json/cbegin.md new file mode 100644 index 0000000..06504fe --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/cbegin.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::cbegin + +```cpp +const_iterator cbegin() const noexcept; +``` + +Returns an iterator to the first element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `cbegin()`. + + ```cpp + --8<-- "examples/cbegin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/cbegin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md new file mode 100644 index 0000000..e19c3ed --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::cbor_tag_handler_t + +```cpp +enum class cbor_tag_handler_t +{ + error, + ignore, + store +}; +``` + +This enumeration is used in the [`from_cbor`](from_cbor.md) function to choose how to treat tags: + +error +: throw a `parse_error` exception in case of a tag + +ignore +: ignore tags + +store +: store tagged values as binary container with subtype (for bytes 0xd8..0xdb) + +## Examples + +??? example + + The example below shows how the different values of the `cbor_tag_handler_t` influence the behavior of + [`from_cbor`](from_cbor.md) when reading a tagged byte string. + + ```cpp + --8<-- "examples/cbor_tag_handler_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/cbor_tag_handler_t.output" + ``` + +## Version history + +- Added in version 3.9.0. Added value `store` in 3.10.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/cend.md b/json-develop/docs/mkdocs/docs/api/basic_json/cend.md new file mode 100644 index 0000000..3f3aa94 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/cend.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::cend + +```cpp +const_iterator cend() const noexcept; +``` + +Returns an iterator to one past the last element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator one past the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `cend()`. + + ```cpp + --8<-- "examples/cend.cpp" + ``` + + Output: + + ```json + --8<-- "examples/cend.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/clear.md b/json-develop/docs/mkdocs/docs/api/basic_json/clear.md new file mode 100644 index 0000000..ff04b08 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/clear.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::clear + +```cpp +void clear() noexcept; +``` + +Clears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](basic_json.md) would +have been called with the current value type from [`type()`](type.md): + +| Value type | initial value | +|------------|----------------------| +| null | `null` | +| boolean | `false` | +| string | `""` | +| number | `0` | +| binary | An empty byte vector | +| object | `{}` | +| array | `[]` | + +Has the same effect as calling + +```.cpp +*this = basic_json(type()); +``` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +All iterators, pointers and references related to this container are invalidated. + +## Examples + +??? example + + The example below shows the effect of `clear()` to different + JSON types. + + ```cpp + --8<-- "examples/clear.cpp" + ``` + + Output: + + ```json + --8<-- "examples/clear.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added support for binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/contains.md b/json-develop/docs/mkdocs/docs/api/basic_json/contains.md new file mode 100644 index 0000000..ba2c3df --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/contains.md @@ -0,0 +1,118 @@ +# nlohmann::basic_json::contains + +```cpp +// (1) +bool contains(const typename object_t::key_type& key) const; + +// (2) +template +bool contains(KeyType&& key) const; + +// (3) +bool contains(const json_pointer& ptr) const; +``` + +1. Check whether an element exists in a JSON object with a key equivalent to `key`. If the element is not found or the + JSON value is not an object, `#!cpp false` is returned. +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. +3. Check whether the given JSON pointer `ptr` can be resolved in the current JSON value. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`key` (in) +: key value to check its existence. + +`ptr` (in) +: JSON pointer to check its existence. + +## Return value + +1. `#!cpp true` if an element with specified `key` exists. If no such element with such key is found or the JSON value + is not an object, `#!cpp false` is returned. +2. See 1. +3. `#!cpp true` if the JSON pointer can be resolved to a stored value, `#!cpp false` otherwise. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function does not throw exceptions. +2. The function does not throw exceptions. +3. The function can throw the following exceptions: + - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index begins with + `0`. + - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index was not a + number. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +- This method always returns `#!cpp false` when executed on a JSON type that is not an object. +- This method can be executed on any JSON value type. + +!!! info "Postconditions" + + If `#!cpp j.contains(x)` returns `#!c true` for a key or JSON pointer `x`, then it is safe to call `j[x]`. + +## Examples + +??? example "Example: (1) check with key" + + The example shows how `contains()` is used. + + ```cpp + --8<-- "examples/contains__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/contains__object_t_key_type.output" + ``` + +??? example "Example: (2) check with key using string_view" + + The example shows how `contains()` is used. + + ```cpp + --8<-- "examples/contains__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/contains__keytype.c++17.output" + ``` + +??? example "Example: (3) check with JSON pointer" + + The example shows how `contains()` is used. + + ```cpp + --8<-- "examples/contains__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/contains__json_pointer.output" + ``` + +## Version history + +1. Added in version 3.11.0. +2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0. +3. Added in version 3.7.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/count.md b/json-develop/docs/mkdocs/docs/api/basic_json/count.md new file mode 100644 index 0000000..4f3a310 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/count.md @@ -0,0 +1,78 @@ +# nlohmann::basic_json::count + +```cpp +// (1) +size_type count(const typename object_t::key_type& key) const; + +// (2) +template +size_type count(KeyType&& key) const; +``` + +1. Returns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will + always be `0` (`key` was not found) or `1` (`key` was found). +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`key` (in) +: key value of the element to count. + +## Return value + +Number of elements with key `key`. If the JSON value is not an object, the return value will be `0`. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +This method always returns `0` when executed on a JSON type that is not an object. + +## Examples + +??? example "Example: (1) count number of elements" + + The example shows how `count()` is used. + + ```cpp + --8<-- "examples/count__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/count__object_t_key_type.output" + ``` + +??? example "Example: (2) count number of elements using string_view" + + The example shows how `count()` is used. + + ```cpp + --8<-- "examples/count__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/count__keytype.c++17.output" + ``` + +## Version history + +1. Added in version 3.11.0. +2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/crbegin.md b/json-develop/docs/mkdocs/docs/api/basic_json/crbegin.md new file mode 100644 index 0000000..7af5eca --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/crbegin.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::crbegin + +```cpp +const_reverse_iterator crbegin() const noexcept; +``` + +Returns an iterator to the reverse-beginning; that is, the last element. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `crbegin()`. + + ```cpp + --8<-- "examples/crbegin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/crbegin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/crend.md b/json-develop/docs/mkdocs/docs/api/basic_json/crend.md new file mode 100644 index 0000000..0e6bc84 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/crend.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::crend + +```cpp +const_reverse_iterator crend() const noexcept; +``` + +Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, +attempting to access it results in undefined behavior. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the element following the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `eend()`. + + ```cpp + --8<-- "examples/crend.cpp" + ``` + + Output: + + ```json + --8<-- "examples/crend.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md new file mode 100644 index 0000000..8a237f6 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md @@ -0,0 +1,35 @@ +# nlohmann::basic_json::default_object_comparator_t + +```cpp +using default_object_comparator_t = std::less; // until C++14 + +using default_object_comparator_t = std::less<>; // since C++14 +``` + +The default comparator used by [`object_t`](object_t.md). + +Since C++14 a transparent comparator is used which prevents unnecessary string construction +when looking up a key in an object. + +The actual comparator used depends on [`object_t`](object_t.md) and can be obtained via +[`object_comparator_t`](object_comparator_t.md). + +## Examples + +??? example + + The example below demonstrates the default comparator. + + ```cpp + --8<-- "examples/default_object_comparator_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/default_object_comparator_t.output" + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/diff.md b/json-develop/docs/mkdocs/docs/api/basic_json/diff.md new file mode 100644 index 0000000..4e84068 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/diff.md @@ -0,0 +1,62 @@ +# nlohmann::basic_json::diff + +```cpp +static basic_json diff(const basic_json& source, + const basic_json& target); +``` + +Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling +[`patch`](patch.md) function. + +For two JSON values `source` and `target`, the following code yields always `#!cpp true`: +```cpp +source.patch(diff(source, target)) == target; +``` + +## Parameters + +`source` (in) +: JSON value to compare from + +`target` (in) +: JSON value to compare against + +## Return value + +a JSON patch to convert the `source` to `target` + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the lengths of `source` and `target`. + +## Notes + +Currently, only `remove`, `add`, and `replace` operations are generated. + +## Examples + +??? example + + The following code shows how a JSON patch is created as a diff for two JSON values. + + ```cpp + --8<-- "examples/diff.cpp" + ``` + + Output: + + ```json + --8<-- "examples/diff.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) + +## Version history + +- Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/dump.md b/json-develop/docs/mkdocs/docs/api/basic_json/dump.md new file mode 100644 index 0000000..41adb15 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/dump.md @@ -0,0 +1,79 @@ +# nlohmann::basic_json::dump + +```cpp +string_t dump(const int indent = -1, + const char indent_char = ' ', + const bool ensure_ascii = false, + const error_handler_t error_handler = error_handler_t::strict) const; +``` + +Serialization function for JSON values. The function tries to mimic Python's +[`json.dumps()` function](https://docs.python.org/2/library/json.html#json.dump), and currently supports its `indent` +and `ensure_ascii` parameters. + +## Parameters + +`indent` (in) +: If `indent` is nonnegative, then array elements and object members will be pretty-printed with that indent level. An + indent level of `0` will only insert newlines. `-1` (the default) selects the most compact representation. + +`indent_char` (in) +: The character to use for indentation if `indent` is greater than `0`. The default is ` ` (space). + +`ensure_ascii` (in) +: If `ensure_ascii` is true, all non-ASCII characters in the output are escaped with `\uXXXX` sequences, and the + result consists of ASCII characters only. + +`error_handler` (in) +: how to react on decoding errors; there are three possible values (see [`error_handler_t`](error_handler_t.md): + `strict` (throws and exception in case a decoding error occurs; default), `replace` (replace invalid UTF-8 sequences + with U+FFFD), and `ignore` (ignore invalid UTF-8 sequences during serialization; all bytes are copied to the output + unchanged)). + +## Return value + +string containing the serialization of the JSON value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value +is not UTF-8 encoded and `error_handler` is set to `strict` + +## Complexity + +Linear. + +## Notes + +Binary values are serialized as object containing two keys: + +- "bytes": an array of bytes as integers +- "subtype": the subtype as integer or `#!json null` if the binary has no subtype + +## Examples + +??? example + + The following example shows the effect of different `indent`, `indent_char`, and `ensure_ascii` parameters to the + result of the serialization. + + ```cpp + --8<-- "examples/dump.cpp" + ``` + + Output: + + ```json + --8<-- "examples/dump.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Indentation character `indent_char`, option `ensure_ascii` and exceptions added in version 3.0.0. +- Error handlers added in version 3.4.0. +- Serialization of binary values added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/emplace.md b/json-develop/docs/mkdocs/docs/api/basic_json/emplace.md new file mode 100644 index 0000000..6cc2c98 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/emplace.md @@ -0,0 +1,56 @@ +# nlohmann::basic_json::emplace + +```cpp +template +std::pair emplace(Args&& ... args); +``` + +Inserts a new element into a JSON object constructed in-place with the given `args` if there is no element with the key +in the container. If the function is called on a JSON null value, an empty object is created before appending the value +created from `args`. + +## Template parameters + +`Args` +: compatible types to create a `basic_json` object + +## Parameters + +`args` (in) +: arguments to forward to a constructor of `basic_json` + +## Return value + +a pair consisting of an iterator to the inserted element, or the already-existing element if no insertion happened, and +a `#!cpp bool` denoting whether the insertion took place. + +## Exceptions + +Throws [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON +object or `#!json null`; example: `"cannot use emplace() with number"` + +## Complexity + +Logarithmic in the size of the container, O(log(`size()`)). + +## Examples + +??? example + + The example shows how `emplace()` can be used to add elements to a JSON object. Note how the `#!json null` value was + silently converted to a JSON object. Further note how no value is added if there was already one value stored with + the same key. + + ```cpp + --8<-- "examples/emplace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/emplace.output" + ``` + +## Version history + +- Since version 2.0.8. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/emplace_back.md b/json-develop/docs/mkdocs/docs/api/basic_json/emplace_back.md new file mode 100644 index 0000000..597ad41 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/emplace_back.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::emplace_back + +```cpp +template +reference emplace_back(Args&& ... args); +``` + +Creates a JSON value from the passed parameters `args` to the end of the JSON value. If the function is called on a JSON +`#!json null` value, an empty array is created before appending the value created from `args`. + +## Template parameters + +`Args` +: compatible types to create a `basic_json` object + +## Parameters + +`args` (in) +: arguments to forward to a constructor of `basic_json` + +## Return value + +reference to the inserted element + +## Exceptions + +Throws [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON +array or `#!json null`; example: `"cannot use emplace_back() with number"` + +## Complexity + +Amortized constant. + +## Examples + +??? example + + The example shows how `emplace_back()` can be used to add elements to a JSON array. Note how the `null` value was + silently converted to a JSON array. + + ```cpp + --8<-- "examples/emplace_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/emplace_back.output" + ``` + +## Version history + +- Since version 2.0.8. +- Returns reference since 3.7.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/empty.md b/json-develop/docs/mkdocs/docs/api/basic_json/empty.md new file mode 100644 index 0000000..26bf6e9 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/empty.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::empty + +```cpp +bool empty() const noexcept; +``` + +Checks if a JSON value has no elements (i.e. whether its [`size()`](size.md) is `0`). + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +|------------|----------------------------------------| +| null | `#!cpp true` | +| boolean | `#!cpp false` | +| string | `#!cpp false` | +| number | `#!cpp false` | +| binary | `#!cpp false` | +| object | result of function `object_t::empty()` | +| array | result of function `array_t::empty()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the +[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `empty()` functions have +constant complexity. + +## Possible implementation + +```cpp +bool empty() const noexcept +{ + return size() == 0; +} +``` + +## Notes + +This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container +itself is empty which is `#!cpp false` in the case of a string. + +## Examples + +??? example + + The following code uses `empty()` to check if a JSON object contains any elements. + + ```cpp + --8<-- "examples/empty.cpp" + ``` + + Output: + + ```json + --8<-- "examples/empty.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Extended to return `#!cpp false` for binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/end.md b/json-develop/docs/mkdocs/docs/api/basic_json/end.md new file mode 100644 index 0000000..179ce9e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/end.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::end + +```cpp +iterator end() noexcept; +const_iterator end() const noexcept; +``` + +Returns an iterator to one past the last element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator one past the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `end()`. + + ```cpp + --8<-- "examples/end.cpp" + ``` + + Output: + + ```json + --8<-- "examples/end.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/erase.md b/json-develop/docs/mkdocs/docs/api/basic_json/erase.md new file mode 100644 index 0000000..1187995 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/erase.md @@ -0,0 +1,211 @@ +# nlohmann::basic_json::erase + +```cpp +// (1) +iterator erase(iterator pos); +const_iterator erase(const_iterator pos); + +// (2) +iterator erase(iterator first, iterator last); +const_iterator erase(const_iterator first, const_iterator last); + +// (3) +size_type erase(const typename object_t::key_type& key); + +// (4) +template +size_type erase(KeyType&& key); + +// (5) +void erase(const size_type idx); +``` + +1. Removes an element from a JSON value specified by iterator `pos`. The iterator `pos` must be valid and + dereferenceable. Thus, the `end()` iterator (which is valid, but is not dereferenceable) cannot be used as a value for + `pos`. + + If called on a primitive type other than `#!json null`, the resulting JSON value will be `#!json null`. + +2. Remove an element range specified by `[first; last)` from a JSON value. The iterator `first` does not need to be + dereferenceable if `first == last`: erasing an empty range is a no-op. + + If called on a primitive type other than `#!json null`, the resulting JSON value will be `#!json null`. + +3. Removes an element from a JSON object by key. + +4. See 3. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +5. Removes an element from a JSON array by index. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`pos` (in) +: iterator to the element to remove + +`first` (in) +: iterator to the beginning of the range to remove + +`last` (in) +: iterator past the end of the range to remove + +`key` (in) +: object key of the elements to remove + +`idx` (in) +: array index of the element to remove + +## Return value + +1. Iterator following the last removed element. If the iterator `pos` refers to the last element, the `end()` iterator + is returned. +2. Iterator following the last removed element. If the iterator `last` refers to the last element, the `end()` iterator + is returned. +3. Number of elements removed. If `ObjectType` is the default `std::map` type, the return value will always be `0` + (`key` was not found) or `1` (`key` was found). +4. See 3. +5. (none) + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if called on a `null` value; + example: `"cannot use erase() with null"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.205`](../../home/exceptions.md#jsonexceptioninvalid_iterator205) if called on a + primitive type with invalid iterator (i.e., any iterator which is not `begin()`); example: `"iterator out of + range"` +2. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if called on a `null` value; + example: `"cannot use erase() with null"` + - Throws [`invalid_iterator.203`](../../home/exceptions.md#jsonexceptioninvalid_iterator203) if called on iterators + which does not belong to the current JSON value; example: `"iterators do not fit current value"` + - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if called on a + primitive type with invalid iterators (i.e., if `first != begin()` and `last != end()`); example: `"iterators out + of range"` +3. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) when called on a type other than + JSON object; example: `"cannot use erase() with null"` +4. See 3. +5. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) when called on a type other than + JSON object; example: `"cannot use erase() with null"` + - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) when `idx >= size()`; example: + `"array index 17 is out of range"` + +## Complexity + +1. The complexity depends on the type: + - objects: amortized constant + - arrays: linear in distance between `pos` and the end of the container + - strings and binary: linear in the length of the member + - other types: constant +2. The complexity depends on the type: + - objects: `log(size()) + std::distance(first, last)` + - arrays: linear in the distance between `first` and `last`, plus linear + in the distance between `last` and end of the container + - strings and binary: linear in the length of the member + - other types: constant +3. `log(size()) + count(key)` +4. `log(size()) + count(key)` +5. Linear in distance between `idx` and the end of the container. + +## Notes + +1. Invalidates iterators and references at or after the point of the `erase`, including the `end()` iterator. +2. (none) +3. References and iterators to the erased elements are invalidated. Other references and iterators are not affected. +4. See 3. +5. (none) + +## Examples + +??? example "Example: (1) remove element given an iterator" + + The example shows the effect of `erase()` for different JSON types using an iterator. + + ```cpp + --8<-- "examples/erase__IteratorType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__IteratorType.output" + ``` + +??? example "Example: (2) remove elements given an iterator range" + + The example shows the effect of `erase()` for different JSON types using an iterator range. + + ```cpp + --8<-- "examples/erase__IteratorType_IteratorType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__IteratorType_IteratorType.output" + ``` + +??? example "Example: (3) remove element from a JSON object given a key" + + The example shows the effect of `erase()` for different JSON types using an object key. + + ```cpp + --8<-- "examples/erase__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__object_t_key_type.output" + ``` + +??? example "Example: (4) remove element from a JSON object given a key using string_view" + + The example shows the effect of `erase()` for different JSON types using an object key. + + ```cpp + --8<-- "examples/erase__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__keytype.c++17.output" + ``` + +??? example "Example: (5) remove element from a JSON array given an index" + + The example shows the effect of `erase()` using an array index. + + ```cpp + --8<-- "examples/erase__size_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__size_type.output" + ``` + +## Version history + +1. Added in version 1.0.0. Added support for binary types in version 3.8.0. +2. Added in version 1.0.0. Added support for binary types in version 3.8.0. +3. Added in version 1.0.0. +4. Added in version 3.11.0. +5. Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/error_handler_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/error_handler_t.md new file mode 100644 index 0000000..dc32ced --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/error_handler_t.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::error_handler_t + +```cpp +enum class error_handler_t { + strict, + replace, + ignore +}; +``` + +This enumeration is used in the [`dump`](dump.md) function to choose how to treat decoding errors while serializing a +`basic_json` value. Three values are differentiated: + +strict +: throw a `type_error` exception in case of invalid UTF-8 + +replace +: replace invalid UTF-8 sequences with U+FFFD (� REPLACEMENT CHARACTER) + +ignore +: ignore invalid UTF-8 sequences; all bytes are copied to the output unchanged + +## Examples + +??? example + + The example below shows how the different values of the `error_handler_t` influence the behavior of + [`dump`](dump.md) when reading serializing an invalid UTF-8 sequence. + + ```cpp + --8<-- "examples/error_handler_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/error_handler_t.output" + ``` + +## Version history + +- Added in version 3.4.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/exception.md b/json-develop/docs/mkdocs/docs/api/basic_json/exception.md new file mode 100644 index 0000000..b492666 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/exception.md @@ -0,0 +1,75 @@ +# nlohmann::basic_json::exception + +```cpp +class exception : public std::exception; +``` + +This class is an extension of [`std::exception`](https://en.cppreference.com/w/cpp/error/exception) objects with a +member `id` for exception ids. It is used as the base class for all exceptions thrown by the `basic_json` class. This +class can hence be used as "wildcard" to catch exceptions, see example below. + +```plantuml +std::exception <|-- basic_json::exception +basic_json::exception <|-- basic_json::parse_error +basic_json::exception <|-- basic_json::invalid_iterator +basic_json::exception <|-- basic_json::type_error +basic_json::exception <|-- basic_json::out_of_range +basic_json::exception <|-- basic_json::other_error + +interface std::exception {} + +class basic_json::exception #FFFF00 { + + const int id + + const char* what() const +} + +class basic_json::parse_error { + + const std::size_t byte +} +``` + +Subclasses: + +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Notes + +To have nothrow-copy-constructible exceptions, we internally use `std::runtime_error` which can cope with +arbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual +constructor. + +## Examples + +??? example + + The following code shows how arbitrary library exceptions can be caught. + + ```cpp + --8<-- "examples/exception.cpp" + ``` + + Output: + + ```json + --8<-- "examples/exception.output" + ``` + +## See also + +[List of exceptions](127.0.0.1:8000/home/exceptions/) + +## Version history + +- Since version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/find.md b/json-develop/docs/mkdocs/docs/api/basic_json/find.md new file mode 100644 index 0000000..c643507 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/find.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::find + +```cpp +// (1) +iterator find(const typename object_t::key_type& key); +const_iterator find(const typename object_t::key_type& key) const; + +// (2) +template +iterator find(KeyType&& key); +template +const_iterator find(KeyType&& key) const; +``` + +1. Finds an element in a JSON object with a key equivalent to `key`. If the element is not found or the + JSON value is not an object, `end()` is returned. +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`key` (in) +: key value of the element to search for. + +## Return value + +Iterator to an element with a key equivalent to `key`. If no such element is found or the JSON value is not an object, +a past-the-end iterator (see `end()`) is returned. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +This method always returns `end()` when executed on a JSON type that is not an object. + +## Examples + +??? example "Example: (1) find object element by key" + + The example shows how `find()` is used. + + ```cpp + --8<-- "examples/find__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/find__object_t_key_type.output" + ``` + +??? example "Example: (2) find object element by key using string_view" + + The example shows how `find()` is used. + + ```cpp + --8<-- "examples/find__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/find__keytype.c++17.output" + ``` + +## See also + +- [contains](contains.md) checks whether a key exists + +## Version history + +1. Added in version 3.11.0. +2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/flatten.md b/json-develop/docs/mkdocs/docs/api/basic_json/flatten.md new file mode 100644 index 0000000..8703e86 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/flatten.md @@ -0,0 +1,50 @@ +# nlohmann::basic_json::flatten + +```cpp +basic_json flatten() const; +``` + +The function creates a JSON object whose keys are JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901)) +and whose values are all primitive (see [`is_primitive()`](is_primitive.md) for more information). The original JSON +value can be restored using the [`unflatten()`](unflatten.md) function. + +## Return value + +an object that maps JSON pointers to primitive values + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Linear in the size the JSON value. + +## Notes + +Empty objects and arrays are flattened to `#!json null` and will not be reconstructed correctly by the +[`unflatten()`](unflatten.md) function. + +## Examples + +??? example + + The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers. + + ```cpp + --8<-- "examples/flatten.cpp" + ``` + + Output: + + ```json + --8<-- "examples/flatten.output" + ``` + +## See also + +- [unflatten](unflatten.md) the reverse function + +## Version history + +- Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/from_bjdata.md b/json-develop/docs/mkdocs/docs/api/basic_json/from_bjdata.md new file mode 100644 index 0000000..3c5eeb3 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/from_bjdata.md @@ -0,0 +1,93 @@ +# nlohmann::basic_json::from_bjdata + +```cpp +// (1) +template +static basic_json from_bjdata(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_bjdata(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the BJData (Binary JData) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/bjdata.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in BJData format convertible to an input adapter + +`first` (in) +: iterator to start of the input + +`last` (in) +: iterator to end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed + successfully + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in BJData format to a JSON value. + + ```cpp + --8<-- "examples/from_bjdata.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bjdata.output" + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/from_bson.md b/json-develop/docs/mkdocs/docs/api/basic_json/from_bson.md new file mode 100644 index 0000000..7754937 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/from_bson.md @@ -0,0 +1,110 @@ +# nlohmann::basic_json::from_bson + +```cpp +// (1) +template +static basic_json from_bson(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_bson(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the BSON (Binary JSON) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/bson.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in BSON format convertible to an input adapter + +`first` (in) +: iterator to start of the input + +`last` (in) +: iterator to end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +Throws [`parse_error.114`](../../home/exceptions.md#jsonexceptionparse_error114) if an unsupported BSON record type is +encountered. + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in BSON format to a JSON value. + + ```cpp + --8<-- "examples/from_bson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bson.output" + ``` + +## See also + +- [BSON specification](http://bsonspec.org/spec.html) +- [to_bson](to_bson.md) for the analogous serialization +- [from_cbor](from_cbor.md) for the related CBOR format +- [from_msgpack](from_msgpack.md) for the related MessagePack format +- [from_ubjson](from_ubjson.md) for the related UBJSON format + +## Version history + +- Added in version 3.4.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_bson` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_bson(ptr, len, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_bson` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_bson({ptr, ptr+len}, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/from_cbor.md b/json-develop/docs/mkdocs/docs/api/basic_json/from_cbor.md new file mode 100644 index 0000000..3aa57b9 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/from_cbor.md @@ -0,0 +1,117 @@ +# nlohmann::basic_json::from_cbor + +```cpp +// (1) +template +static basic_json from_cbor(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); + +// (2) +template +static basic_json from_cbor(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); +``` + +Deserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/cbor.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in CBOR format convertible to an input adapter + +`first` (in) +: iterator to start of the input + +`last` (in) +: iterator to end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`tag_handler` (in) +: how to treat CBOR tags (optional, `error` by default); see [`cbor_tag_handler_t`](cbor_tag_handler_t.md) for more + information + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from CBOR were + used in the given input or if the input is not valid CBOR +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as map key, + but not found + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in CBOR format to a JSON value. + + ```cpp + --8<-- "examples/from_cbor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_cbor.output" + ``` + +## Version history + +- Added in version 2.0.9. +- Parameter `start_index` since version 2.1.1. +- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. +- Added `allow_exceptions` parameter in version 3.2.0. +- Added `tag_handler` parameter in version 3.9.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_cbor` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_cbor(ptr, len, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_cbor({ptr, ptr+len}, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/from_msgpack.md b/json-develop/docs/mkdocs/docs/api/basic_json/from_msgpack.md new file mode 100644 index 0000000..117c386 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/from_msgpack.md @@ -0,0 +1,109 @@ +# nlohmann::basic_json::from_msgpack + +```cpp +// (1) +template +static basic_json from_msgpack(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_msgpack(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the MessagePack serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/messagepack.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in MessagePack format convertible to an input adapter + +`first` (in) +: iterator to start of the input + +`last` (in) +: iterator to end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from + MessagePack were used in the given input or if the input is not valid MessagePack +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as map key, + but not found + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in MessagePack format to a JSON value. + + ```cpp + --8<-- "examples/from_msgpack.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_msgpack.output" + ``` + +## Version history + +- Added in version 2.0.9. +- Parameter `start_index` since version 2.1.1. +- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. +- Added `allow_exceptions` parameter in version 3.2.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_msgpack` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_msgpack(ptr, len, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_msgpack({ptr, ptr+len}, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/from_ubjson.md b/json-develop/docs/mkdocs/docs/api/basic_json/from_ubjson.md new file mode 100644 index 0000000..08117e8 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/from_ubjson.md @@ -0,0 +1,106 @@ +# nlohmann::basic_json::from_ubjson + +```cpp +// (1) +template +static basic_json from_ubjson(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_ubjson(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/ubjson.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in UBJSON format convertible to an input adapter + +`first` (in) +: iterator to start of the input + +`last` (in) +: iterator to end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed + successfully + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in UBJSON format to a JSON value. + + ```cpp + --8<-- "examples/from_ubjson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_ubjson.output" + ``` + +## Version history + +- Added in version 3.1.0. +- Added `allow_exceptions` parameter in version 3.2.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_ubjson` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_ubjson(ptr, len, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_ubjson` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_ubjson({ptr, ptr+len}, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/front.md b/json-develop/docs/mkdocs/docs/api/basic_json/front.md new file mode 100644 index 0000000..e258c36 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/front.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::front + +```cpp +reference front(); +const_reference front() const; +``` + +Returns a reference to the first element in the container. For a JSON container `#!cpp c`, the expression +`#!cpp c.front()` is equivalent to `#!cpp *c.begin()`. + +## Return value + +In case of a structured type (array or object), a reference to the first element is returned. In case of number, string, +boolean, or binary values, a reference to the value is returned. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +If the JSON value is `#!json null`, exception +[`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) is thrown. + +## Complexity + +Constant. + +## Notes + +!!! info "Precondition" + + The array or object must not be empty. Calling `front` on an empty array or object yields undefined behavior. + +## Examples + +??? example + + The following code shows an example for `front()`. + + ```cpp + --8<-- "examples/front.cpp" + ``` + + Output: + + ```json + --8<-- "examples/front.output" + ``` + +## See also + +- [back](back.md) to access the last element + +## Version history + +- Added in version 1.0.0. +- Adjusted code to return reference to binary values in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/get.md b/json-develop/docs/mkdocs/docs/api/basic_json/get.md new file mode 100644 index 0000000..96fc221 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/get.md @@ -0,0 +1,136 @@ +# nlohmann::basic_json::get + +```cpp +// (1) +template +ValueType get() const noexcept( + noexcept(JSONSerializer::from_json( + std::declval(), std::declval()))); + +// (2) +template +BasicJsonType get() const; + +// (3) +template +PointerType get_ptr(); + +template +constexpr const PointerType get_ptr() const noexcept; +``` + +1. Explicit type conversion between the JSON value and a compatible value which is + [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and + [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). The value is converted by + calling the `json_serializer` `from_json()` method. + + The function is equivalent to executing + ```cpp + ValueType ret; + JSONSerializer::from_json(*this, ret); + return ret; + ``` + + This overload is chosen if: + + - `ValueType` is not `basic_json`, + - `json_serializer` has a `from_json()` method of the form + `void from_json(const basic_json&, ValueType&)`, and + - `json_serializer` does not have a `from_json()` method of the form + `ValueType from_json(const basic_json&)` + + If the type is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and + **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible), the value is + converted by calling the `json_serializer` `from_json()` method. + + The function is then equivalent to executing + ```cpp + return JSONSerializer::from_json(*this); + ``` + + This overload is chosen if: + + - `ValueType` is not `basic_json` and + - `json_serializer` has a `from_json()` method of the form + `ValueType from_json(const basic_json&)` + + If `json_serializer` has both overloads of `from_json()`, the latter one is chosen. + +2. Overload for `basic_json` specializations. The function is equivalent to executing + ```cpp + return *this; + ``` + +3. Explicit pointer access to the internally stored JSON value. No copies are made. + +## Template parameters + +`ValueType` +: the value type to return + +`BasicJsonType` +: a specialization of `basic_json` + +`PointerType` +: pointer type; must be a pointer to [`array_t`](array_t.md), [`object_t`](object_t.md), [`string_t`](string_t.md), + [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or + [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md). + Other types will not compile. + +## Return value + +1. copy of the JSON value, converted to `ValueType` +2. a copy of `#!cpp *this`, converted into `BasicJsonType` +3. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr` + otherwise + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Notes + +!!! danger "Undefined behavior" + + Writing data to the pointee (overload 3) of the result yields an undefined state. + +## Examples + +??? example + + The example below shows several conversions from JSON values + to other types. There a few things to note: (1) Floating-point numbers can + be converted to integers, (2) A JSON array can be converted to a standard + `std::vector`, (3) A JSON object can be converted to C++ + associative containers such as `std::unordered_map`. + + ```cpp + --8<-- "examples/get__ValueType_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get__ValueType_const.output" + ``` + +??? example + + The example below shows how pointers to internal values of a JSON value can be requested. Note that no type + conversions are made and a `#cpp nullptr` is returned if the value and the requested pointer type does not match. + + ```cpp + --8<-- "examples/get__PointerType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get__PointerType.output" + ``` + +## Version history + +1. Since version 2.1.0. +2. Since version 2.1.0. Extended to work with other specializations of `basic_json` in version 3.2.0. +3. Since version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/get_allocator.md b/json-develop/docs/mkdocs/docs/api/basic_json/get_allocator.md new file mode 100644 index 0000000..07a4d84 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/get_allocator.md @@ -0,0 +1,31 @@ +# nlohmann::basic_json::get_allocator + +```cpp +static allocator_type get_allocator(); +``` + +Returns the allocator associated with the container. + +## Return value + +associated allocator + +## Examples + +??? example + + The example shows how `get_allocator()` is used to created `json` values. + + ```cpp + --8<-- "examples/get_allocator.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_allocator.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/get_binary.md b/json-develop/docs/mkdocs/docs/api/basic_json/get_binary.md new file mode 100644 index 0000000..a910f3a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/get_binary.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json::get_binary + +```cpp +binary_t& get_binary(); + +const binary_t& get_binary() const; +``` + +Returns a reference to the stored binary value. + +## Return value + +Reference to binary value. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if the value is not binary + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows how to query a binary value. + + ```cpp + --8<-- "examples/get_binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/get_ptr.md b/json-develop/docs/mkdocs/docs/api/basic_json/get_ptr.md new file mode 100644 index 0000000..2441e11 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/get_ptr.md @@ -0,0 +1,60 @@ +# nlohmann::basic_json::get_ptr + +```cpp +template +PointerType get_ptr() noexcept; + +template +constexpr const PointerType get_ptr() const noexcept; +``` + +Implicit pointer access to the internally stored JSON value. No copies are made. + +## Template parameters + +`PointerType` +: pointer type; must be a pointer to [`array_t`](array_t.md), [`object_t`](object_t.md), [`string_t`](string_t.md), + [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or + [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md). + Other types will not compile. + +## Return value + +pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr` +otherwise + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +!!! danger "Undefined behavior" + + Writing data to the pointee of the result yields an undefined state. + +## Examples + +??? example + + The example below shows how pointers to internal values of a JSON value can be requested. Note that no type + conversions are made and a `#!cpp nullptr` is returned if the value and the requested pointer type does not match. + + ```cpp + --8<-- "examples/get_ptr.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_ptr.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Extended to binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/get_ref.md b/json-develop/docs/mkdocs/docs/api/basic_json/get_ref.md new file mode 100644 index 0000000..b121974 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/get_ref.md @@ -0,0 +1,64 @@ +# nlohmann::basic_json::get_ref + +```cpp +template +ReferenceType get_ref(); + +template +const ReferenceType get_ref() const; +``` + +Implicit reference access to the internally stored JSON value. No copies are made. + +## Template parameters + +`ReferenceType` +: reference type; must be a reference to [`array_t`](array_t.md), [`object_t`](object_t.md), + [`string_t`](string_t.md), [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or + [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md). + Enforced by a static assertion. + +## Return value + +reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws +[`type_error.303`](../../home/exceptions.md#jsonexceptiontype_error303) otherwise + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +Throws [`type_error.303`](../../home/exceptions.md#jsonexceptiontype_error303) if the requested reference type does not +match the stored JSON value type; example: `"incompatible ReferenceType for get_ref, actual type is binary"`. + +## Complexity + +Constant. + +## Notes + +!!! danger "Undefined behavior" + + Writing data to the referee of the result yields an undefined state. + +## Examples + +??? example + + The example shows several calls to `get_ref()`. + + ```cpp + --8<-- "examples/get_ref.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_ref.output" + ``` + +## Version history + +- Added in version 1.1.0. +- Extended to binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/get_to.md b/json-develop/docs/mkdocs/docs/api/basic_json/get_to.md new file mode 100644 index 0000000..6af6d21 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/get_to.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::get_to + +```cpp +template +ValueType& get_to(ValueType& v) const noexcept( + noexcept(JSONSerializer::from_json( + std::declval(), v))); +``` + +Explicit type conversion between the JSON value and a compatible value. The value is filled into the input parameter by +calling the `json_serializer` `from_json()` method. + +The function is equivalent to executing +```cpp +ValueType v; +JSONSerializer::from_json(*this, v); +``` + +This overload is chosen if: + +- `ValueType` is not `basic_json`, +- `json_serializer` has a `from_json()` method of the form `void from_json(const basic_json&, ValueType&)` + +## Template parameters + +`ValueType` +: the value type to return + +## Return value + +the input parameter, allowing chaining calls + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Examples + +??? example + + The example below shows several conversions from JSON values to other types. There a few things to note: (1) + Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard + `#!cpp std::vector`, (3) A JSON object can be converted to C++ associative containers such as + `#cpp std::unordered_map`. + + ```cpp + --8<-- "examples/get_to.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_to.output" + ``` + +## Version history + +- Since version 3.3.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/index.md b/json-develop/docs/mkdocs/docs/api/basic_json/index.md new file mode 100644 index 0000000..fb2be8f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/index.md @@ -0,0 +1,323 @@ +# nlohmann::basic_json + +Defined in header `` + +```cpp +template< + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer, + class BinaryType = std::vector +> +class basic_json; +``` + +## Template parameters + +| Template parameter | Description | Derived type | +|----------------------|---------------------------------------------------------------------------|---------------------------------------------| +| `ObjectType` | type for JSON objects | [`object_t`](object_t.md) | +| `ArrayType` | type for JSON arrays | [`array_t`](array_t.md) | +| `StringType` | type for JSON strings and object keys | [`string_t`](string_t.md) | +| `BooleanType` | type for JSON booleans | [`boolean_t`](boolean_t.md) | +| `NumberIntegerType` | type for JSON integer numbers | [`number_integer_t`](number_integer_t.md) | +| `NumberUnsignedType` | type for JSON unsigned integer numbers | [`number_unsigned_t`](number_unsigned_t.md) | +| `NumberFloatType` | type for JSON floating-point numbers | [`number_float_t`](number_float_t.md) | +| `AllocatorType` | type of the allocator to use | | +| `JSONSerializer` | the serializer to resolve internal calls to `to_json()` and `from_json()` | [`json_serializer`](json_serializer.md) | +| `BinaryType` | type for binary arrays | [`binary_t`](binary_t.md) | +| `CustomBaseClass` | extension point for user code | [`json_base_class_t`](json_base_class_t.md) | + +## Specializations + +- [**json**](../json.md) - default specialization +- [**ordered_json**](../ordered_json.md) - specialization that maintains the insertion order of object keys + +## Iterator invalidation + +Todo + +## Requirements + +The class satisfies the following concept requirements: + +### Basic + +- [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): JSON values can be default + constructed. The result will be a JSON null value. +- [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): A JSON value can be constructed + from an rvalue argument. +- [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): A JSON value can be + copy-constructed from an lvalue expression. +- [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): A JSON value can be assigned from an + rvalue argument. +- [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): A JSON value can be copy-assigned from + an lvalue expression. +- [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): JSON values can be destructed. + +### Layout + +- [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): JSON values have + [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): All non-static data + members are private and standard layout types, the class has no virtual functions or (virtual) base classes. + +### Library-wide + +- [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): JSON values can be compared with + `==`, see [`operator==`](operator_eq.md). +- [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): JSON values can be compared with + `<`, see [`operator<`](operator_le). +- [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): Any JSON lvalue or rvalue of can be swapped with + any lvalue or rvalue of other compatible types, using unqualified function `swap`. +- [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): JSON values can be compared against + `std::nullptr_t` objects which are used to model the `null` value. + +### Container + +- [Container](https://en.cppreference.com/w/cpp/named_req/Container): JSON values can be used like STL containers and + provide iterator access. +- [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer): JSON values can be used like + STL containers and provide reverse iterator access. + +## Member types + +- [**adl_serializer**](../adl_serializer) - the default serializer +- [**value_t**](value_t.md) - the JSON type enumeration +- [**json_pointer**](../json_pointer/index.md) - JSON Pointer implementation +- [**json_serializer**](json_serializer.md) - type of the serializer to for conversions from/to JSON +- [**error_handler_t**](error_handler_t.md) - type to choose behavior on decoding errors +- [**cbor_tag_handler_t**](cbor_tag_handler_t.md) - type to choose how to handle CBOR tags +- **initializer_list_t** - type for initializer lists of `basic_json` values +- [**input_format_t**](input_format_t.md) - type to choose the format to parse +- [**json_sax_t**](../json_sax/index.md) - type for SAX events + +### Exceptions + +- [**exception**](exception.md) - general exception of the `basic_json` class + - [**parse_error**](parse_error.md) - exception indicating a parse error + - [**invalid_iterator**](invalid_iterator.md) - exception indicating errors with iterators + - [**type_error**](type_error.md) - exception indicating executing a member function with a wrong type + - [**out_of_range**](out_of_range.md) - exception indicating access out of the defined range + - [**other_error**](other_error.md) - exception indicating other library errors + +### Container types + +| Type | Definition | +|--------------------------|-----------------------------------------------------------------------------------------------------------| +| `value_type` | `#!cpp basic_json` | +| `reference` | `#!cpp value_type&` | +| `const_reference` | `#!cpp const value_type&` | +| `difference_type` | `#!cpp std::ptrdiff_t` | +| `size_type` | `#!cpp std::size_t` | +| `allocator_type` | `#!cpp AllocatorType` | +| `pointer` | `#!cpp std::allocator_traits::pointer` | +| `const_pointer` | `#!cpp std::allocator_traits::const_pointer` | +| `iterator` | [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| `const_iterator` | constant [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| `reverse_iterator` | reverse iterator, derived from `iterator` | +| `const_reverse_iterator` | reverse iterator, derived from `const_iterator` | +| `iteration_proxy` | helper type for [`items`](items.md) function | + +### JSON value data types + +- [**array_t**](array_t.md) - type for arrays +- [**binary_t**](binary_t.md) - type for binary arrays +- [**boolean_t**](boolean_t.md) - type for booleans +- [**default_object_comparator_t**](default_object_comparator_t.md) - default comparator for objects +- [**number_float_t**](number_float_t.md) - type for numbers (floating-point) +- [**number_integer_t**](number_integer_t.md) - type for numbers (integer) +- [**number_unsigned_t**](number_unsigned_t.md) - type for numbers (unsigned) +- [**object_comparator_t**](object_comparator_t.md) - comparator for objects +- [**object_t**](object_t.md) - type for objects +- [**string_t**](string_t.md) - type for strings + +### Parser callback + +- [**parse_event_t**](parse_event_t.md) - parser event types +- [**parser_callback_t**](parser_callback_t.md) - per-element parser callback type + +## Member functions + +- [(constructor)](basic_json.md) +- [(destructor)](~basic_json.md) +- [**operator=**](operator=.md) - copy assignment +- [**array**](array_t.md) (_static_) - explicitly create an array +- [**binary**](binary.md) (_static_) - explicitly create a binary array +- [**object**](object_t.md) (_static_) - explicitly create an object + +### Object inspection + +Functions to inspect the type of a JSON value. + +- [**type**](type.md) - return the type of the JSON value +- [**operator value_t**](operator_value_t.md) - return the type of the JSON value +- [**type_name**](type_name.md) - return the type as string +- [**is_primitive**](is_primitive.md) - return whether type is primitive +- [**is_structured**](is_structured.md) - return whether type is structured +- [**is_null**](is_null.md) - return whether value is null +- [**is_boolean**](is_boolean.md) - return whether value is a boolean +- [**is_number**](is_number.md) - return whether value is a number +- [**is_number_integer**](is_number_integer.md) - return whether value is an integer number +- [**is_number_unsigned**](is_number_unsigned.md) - return whether value is an unsigned integer number +- [**is_number_float**](is_number_float.md) - return whether value is a floating-point number +- [**is_object**](is_object.md) - return whether value is an object +- [**is_array**](is_array.md) - return whether value is an array +- [**is_string**](is_string.md) - return whether value is a string +- [**is_binary**](is_binary.md) - return whether value is a binary array +- [**is_discarded**](is_discarded.md) - return whether value is discarded + +### Value access + +Direct access to the stored value of a JSON value. + +- [**get**](get.md) - get a value +- [**get_to**](get_to.md) - get a value and write it to a destination +- [**get_ptr**](get_ptr.md) - get a pointer value +- [**get_ref**](get_ref.md) - get a reference value +- [**operator ValueType**](operator_ValueType.md) - get a value +- [**get_binary**](get_binary.md) - get a binary value + +### Element access + +Access to the JSON value + +- [**at**](at.md) - access specified element with bounds checking +- [**operator[]**](operator[].md) - access specified element +- [**value**](value.md) - access specified object element with default value +- [**front**](front.md) - access the first element +- [**back**](back.md) - access the last element + +### Lookup + +- [**find**](find.md) - find an element in a JSON object +- [**count**](count.md) - returns the number of occurrences of a key in a JSON object +- [**contains**](contains.md) - check the existence of an element in a JSON object + +### Iterators + +- [**begin**](begin.md) - returns an iterator to the first element +- [**cbegin**](cbegin.md) - returns a const iterator to the first element +- [**end**](end.md) - returns an iterator to one past the last element +- [**cend**](cend.md) - returns a const iterator to one past the last element +- [**rbegin**](rbegin.md) - returns an iterator to the reverse-beginning +- [**rend**](rend.md) - returns an iterator to the reverse-end +- [**crbegin**](crbegin.md) - returns a const iterator to the reverse-beginning +- [**crend**](crend.md) - returns a const iterator to the reverse-end +- [**items**](items.md) - wrapper to access iterator member functions in range-based for + +### Capacity + +- [**empty**](empty.md) - checks whether the container is empty +- [**size**](size.md) - returns the number of elements +- [**max_size**](max_size.md) - returns the maximum possible number of elements + +### Modifiers + +- [**clear**](clear.md) - clears the contents +- [**push_back**](push_back.md) - add a value to an array/object +- [**operator+=**](operator+=.md) - add a value to an array/object +- [**emplace_back**](emplace_back.md) - add a value to an array +- [**emplace**](emplace.md) - add a value to an object if key does not exist +- [**erase**](erase.md) - remove elements +- [**insert**](insert.md) - inserts elements +- [**update**](update.md) - updates a JSON object from another object, overwriting existing keys +- [**swap**](swap.md) - exchanges the values + +### Lexicographical comparison operators + +- [**operator==**](operator_eq.md) - comparison: equal +- [**operator!=**](operator_ne.md) - comparison: not equal +- [**operator<**](operator_lt.md) - comparison: less than +- [**operator>**](operator_gt.md) - comparison: greater than +- [**operator<=**](operator_le.md) - comparison: less than or equal +- [**operator>=**](operator_ge.md) - comparison: greater than or equal +- [**operator<=>**](operator_spaceship.md) - comparison: 3-way + +### Serialization / Dumping + +- [**dump**](dump.md) - serialization + +### Deserialization / Parsing + +- [**parse**](parse.md) (_static_) - deserialize from a compatible input +- [**accept**](accept.md) (_static_) - check if the input is valid JSON +- [**sax_parse**](sax_parse.md) (_static_) - generate SAX events + +### JSON Pointer functions + +- [**flatten**](flatten.md) - return flattened JSON value +- [**unflatten**](unflatten.md) - unflatten a previously flattened JSON value + +### JSON Patch functions + +- [**patch**](patch.md) - applies a JSON patch +- [**patch_inplace**](patch_inplace.md) - applies a JSON patch in place +- [**diff**](diff.md) (_static_) - creates a diff as a JSON patch + +### JSON Merge Patch functions + +- [**merge_patch**](merge_patch.md) - applies a JSON Merge Patch + +## Static functions + +- [**meta**](meta.md) - returns version information on the library +- [**get_allocator**](get_allocator.md) - returns the allocator associated with the container + +### Binary formats + +- [**from_bjdata**](from_bjdata.md) (_static_) - create a JSON value from an input in BJData format +- [**from_bson**](from_bson.md) (_static_) - create a JSON value from an input in BSON format +- [**from_cbor**](from_cbor.md) (_static_) - create a JSON value from an input in CBOR format +- [**from_msgpack**](from_msgpack.md) (_static_) - create a JSON value from an input in MessagePack format +- [**from_ubjson**](from_ubjson.md) (_static_) - create a JSON value from an input in UBJSON format +- [**to_bjdata**](to_bjdata.md) (_static_) - create a BJData serialization of a given JSON value +- [**to_bson**](to_bson.md) (_static_) - create a BSON serialization of a given JSON value +- [**to_cbor**](to_cbor.md) (_static_) - create a CBOR serialization of a given JSON value +- [**to_msgpack**](to_msgpack.md) (_static_) - create a MessagePack serialization of a given JSON value +- [**to_ubjson**](to_ubjson.md) (_static_) - create a UBJSON serialization of a given JSON value + +## Non-member functions + +- [**operator<<(std::ostream&)**](../operator_ltlt.md) - serialize to stream +- [**operator>>(std::istream&)**](../operator_gtgt.md) - deserialize from stream +- [**to_string**](to_string.md) - user-defined `to_string` function for JSON values + +## Literals + +- [**operator""_json**](../operator_literal_json.md) - user-defined string literal for JSON values + +## Helper classes + +- [**std::hash<basic_json>**](std_hash.md) - return a hash value for a JSON object +- [**std::swap<basic_json>**](std_swap.md) - exchanges the values of two JSON objects + +## Examples + +??? example + + The example shows how the library is used. + + ```cpp + --8<-- "examples/README.cpp" + ``` + + Output: + + ```json + --8<-- "examples/README.output" + ``` + +## See also + +- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259) + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/input_format_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/input_format_t.md new file mode 100644 index 0000000..a3baaba --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/input_format_t.md @@ -0,0 +1,52 @@ +# nlohmann::basic_json::input_format_t + +```cpp +enum class input_format_t { + json, + cbor, + msgpack, + ubjson, + bson, + bjdata +}; +``` + +This enumeration is used in the [`sax_parse`](sax_parse.md) function to choose the input format to parse: + +json +: JSON (JavaScript Object Notation) + +cbor +: CBOR (Concise Binary Object Representation) + +msgpack +: MessagePack + +ubjson +: UBJSON (Universal Binary JSON) + +bson +: BSON (Binary JSON) + +bjdata +: BJData (Binary JData) + +## Examples + +??? example + + The example below shows how an `input_format_t` enum value is passed to `sax_parse` to set the input format to CBOR. + + ```cpp + --8<-- "examples/sax_parse__binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse__binary.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/insert.md b/json-develop/docs/mkdocs/docs/api/basic_json/insert.md new file mode 100644 index 0000000..2e6b293 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/insert.md @@ -0,0 +1,179 @@ +# nlohmann::basic_json::insert + +```cpp +// (1) +iterator insert(const_iterator pos, const basic_json& val); +iterator insert(const_iterator pos, basic_json&& val); + +// (2) +iterator insert(const_iterator pos, size_type cnt, const basic_json& val); + +// (3) +iterator insert(const_iterator pos, const_iterator first, const_iterator last); + +// (4) +iterator insert(const_iterator pos, initializer_list_t ilist); + +// (5) +void insert(const_iterator first, const_iterator last); +``` + +1. Inserts element `val` into array before iterator `pos`. +2. Inserts `cnt` copies of `val` into array before iterator `pos`. +3. Inserts elements from range `[first, last)` into array before iterator `pos`. +4. Inserts elements from initializer list `ilist` into array before iterator `pos`. +5. Inserts elements from range `[first, last)` into object. + +## Parameters + +`pos` (in) +: iterator before which the content will be inserted; may be the `end()` iterator + +`val` (in) +: value to insert + +`cnt` (in) +: number of copies of `val` to insert + +`first` (in) +: begin of the range of elements to insert + +`last` (in) +: end of the range of elements to insert + +`ilist` (in) +: initializer list to insert the values from + +## Return value + +1. iterator pointing to the inserted `val`. +2. iterator pointing to the first element inserted, or `pos` if `#!cpp cnt==0` +3. iterator pointing to the first element inserted, or `pos` if `#!cpp first==last` +4. iterator pointing to the first element inserted, or `pos` if `ilist` is empty +5. (none) + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +2. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +3. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last` + do not belong to the same JSON value; example: `"iterators do not fit"` + - Throws [`invalid_iterator.211`](../../home/exceptions.md#jsonexceptioninvalid_iterator211) if `first` or `last` + are iterators into container for which insert is called; example: `"passed iterators may not belong to container"` +4. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +5. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + objects; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last` + do not belong to the same JSON value; example: `"iterators do not fit"` + +## Complexity + +1. Constant plus linear in the distance between `pos` and end of the container. +2. Linear in `cnt` plus linear in the distance between `pos` and end of the container. +3. Linear in `#!cpp std::distance(first, last)` plus linear in the distance between `pos` and end of the container. +4. Linear in `ilist.size()` plus linear in the distance between `pos` and end of the container. +5. Logarithmic: `O(N*log(size() + N))`, where `N` is the number of elements to insert. + +## Examples + +??? example "Example (1): insert element into array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert.output" + ``` + +??? example "Example (2): insert copies of element into array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__count.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__count.output" + ``` + +??? example "Example (3): insert range of elements into array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__range.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__range.output" + ``` + +??? example "Example (4): insert elements from initializer list into array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__ilist.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__ilist.output" + ``` + +??? example "Example (5): insert range of elements into object" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__range_object.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__range_object.output" + ``` + +## Version history + +1. Added in version 1.0.0. +2. Added in version 1.0.0. +3. Added in version 1.0.0. +4. Added in version 1.0.0. +5. Added in version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/invalid_iterator.md b/json-develop/docs/mkdocs/docs/api/basic_json/invalid_iterator.md new file mode 100644 index 0000000..f9fdce5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/invalid_iterator.md @@ -0,0 +1,67 @@ +# nlohmann::basic_json::invalid_iterator + +```cpp +class invalid_iterator : public exception; +``` + +This exception is thrown if iterators passed to a library function do not match the expected semantics. + +Exceptions have ids 2xx (see [list of iterator errors](../../home/exceptions.md#iterator-errors)). + +```plantuml +std::exception <|-- basic_json::exception +basic_json::exception <|-- basic_json::parse_error +basic_json::exception <|-- basic_json::invalid_iterator +basic_json::exception <|-- basic_json::type_error +basic_json::exception <|-- basic_json::out_of_range +basic_json::exception <|-- basic_json::other_error + +interface std::exception {} + +class basic_json::exception { + + const int id + + const char* what() const +} + +class basic_json::parse_error { + + const std::size_t byte +} + +class basic_json::invalid_iterator #FFFF00 {} +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `invalid_iterator` exception can be caught. + + ```cpp + --8<-- "examples/invalid_iterator.cpp" + ``` + + Output: + + ```json + --8<-- "examples/invalid_iterator.output" + ``` + +## See also + +- [List of iterator errors](../../home/exceptions.md#iterator-errors) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_array.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_array.md new file mode 100644 index 0000000..64468c3 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_array.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_array + +```cpp +constexpr bool is_array() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is an array. + +## Return value + +`#!cpp true` if type is an array, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_array()` for all JSON types. + + ```cpp + --8<-- "examples/is_array.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_array.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_binary.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_binary.md new file mode 100644 index 0000000..ea48d74 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_binary.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_binary + +```cpp +constexpr bool is_binary() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is binary array. + +## Return value + +`#!cpp true` if type is binary, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_binary()` for all JSON types. + + ```cpp + --8<-- "examples/is_binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_boolean.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_boolean.md new file mode 100644 index 0000000..dc41d84 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_boolean.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_boolean + +```cpp +constexpr bool is_boolean() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is `#!json true` or `#!json false`. + +## Return value + +`#!cpp true` if type is boolean, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_boolean()` for all JSON types. + + ```cpp + --8<-- "examples/is_boolean.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_boolean.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_discarded.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_discarded.md new file mode 100644 index 0000000..663cbf8 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_discarded.md @@ -0,0 +1,72 @@ +# nlohmann::basic_json::is_discarded + +```cpp +constexpr bool is_discarded() const noexcept; +``` + +This function returns `#!cpp true` for a JSON value if either: + +- the value was discarded during parsing with a callback function (see [`parser_callback_t`](parser_callback_t.md)), or +- the value is the result of parsing invalid JSON with parameter `allow_exceptions` set to `#!cpp false`; see + [`parse`](parse.md) for more information. + +## Return value + +`#!cpp true` if type is discarded, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +!!! note "Comparisons" + + Discarded values are never compared equal with [`operator==`](operator_eq.md). That is, checking whether a JSON + value `j` is discarded will only work via: + + ```cpp + j.is_discarded() + ``` + + because + + ```cpp + j == json::value_t::discarded + ``` + + will always be `#!cpp false`. + +!!! note "Removal during parsing with callback functions" + + When a value is discarded by a callback function (see [`parser_callback_t`](parser_callback_t.md)) during parsing, + then it is removed when it is part of a structured value. For instance, if the second value of an array is discarded, + instead of `#!json [null, discarded, false]`, the array `#!json [null, false]` is returned. Only if the top-level + value is discarded, the return value of the `parse` call is discarded. + +This function will always be `#!cpp false` for JSON values after parsing. That is, discarded values can only occur +during parsing, but will be removed when inside a structured value or replaced by null in other cases. + +## Examples + +??? example + + The following code exemplifies `is_discarded()` for all JSON types. + + ```cpp + --8<-- "examples/is_discarded.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_discarded.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_null.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_null.md new file mode 100644 index 0000000..d080ad3 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_null.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_null + +```cpp +constexpr bool is_null() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is `#!json null`. + +## Return value + +`#!cpp true` if type is `#!json null`, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_null()` for all JSON types. + + ```cpp + --8<-- "examples/is_null.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_null.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_number.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_number.md new file mode 100644 index 0000000..9807911 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_number.md @@ -0,0 +1,56 @@ +# nlohmann::basic_json::is_number + +```cpp +constexpr bool is_number() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a number. This includes both integer (signed and +unsigned) and floating-point values. + +## Return value + +`#!cpp true` if type is number (regardless whether integer, unsigned integer or floating-type), `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +constexpr bool is_number() const noexcept +{ + return is_number_integer() || is_number_float(); +} +``` + +## Examples + +??? example + + The following code exemplifies `is_number()` for all JSON types. + + ```cpp + --8<-- "examples/is_number.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number.output" + ``` + +## See also + +- [is_number_integer()](is_number_integer.md) check if value is an integer or unsigned integer number +- [is_number_unsigned()](is_number_unsigned.md) check if value is an unsigned integer number +- [is_number_float()](is_number_float.md) check if value is a floating-point number + +## Version history + +- Added in version 1.0.0. +- Extended to also return `#!cpp true` for unsigned integers in 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_number_float.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_number_float.md new file mode 100644 index 0000000..68d0cfb --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_number_float.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json::is_number_float + +```cpp +constexpr bool is_number_float() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a floating-point number. This excludes signed and +unsigned integer values. + +## Return value + +`#!cpp true` if type is a floating-point number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_number_float()` for all JSON types. + + ```cpp + --8<-- "examples/is_number_float.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number_float.output" + ``` + +## See also + +- [is_number()](is_number.md) check if value is a number +- [is_number_integer()](is_number_integer.md) check if value is an integer or unsigned integer number +- [is_number_unsigned()](is_number_unsigned.md) check if value is an unsigned integer number + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_number_integer.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_number_integer.md new file mode 100644 index 0000000..8ca214a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_number_integer.md @@ -0,0 +1,47 @@ +# nlohmann::basic_json::is_number_integer + +```cpp +constexpr bool is_number_integer() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a signed or unsigned integer number. This excludes +floating-point values. + +## Return value + +`#!cpp true` if type is an integer or unsigned integer number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_number_integer()` for all JSON types. + + ```cpp + --8<-- "examples/is_number_integer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number_integer.output" + ``` + +## See also + +- [is_number()](is_number.md) check if value is a number +- [is_number_unsigned()](is_number_unsigned.md) check if value is an unsigned integer number +- [is_number_float()](is_number_float.md) check if value is a floating-point number + +## Version history + +- Added in version 1.0.0. +- Extended to also return `#!cpp true` for unsigned integers in 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md new file mode 100644 index 0000000..2ac98a5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json::is_number_unsigned + +```cpp +constexpr bool is_number_unsigned() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is an unsigned integer number. This excludes +floating-point and signed integer values. + +## Return value + +`#!cpp true` if type is an unsigned integer number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_number_unsigned()` for all JSON types. + + ```cpp + --8<-- "examples/is_number_unsigned.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number_unsigned.output" + ``` + +## See also + +- [is_number()](is_number.md) check if value is a number +- [is_number_integer()](is_number_integer.md) check if value is an integer or unsigned integer number +- [is_number_float()](is_number_float.md) check if value is a floating-point number + +## Version history + +- Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_object.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_object.md new file mode 100644 index 0000000..0445701 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_object.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_object + +```cpp +constexpr bool is_object() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is an object. + +## Return value + +`#!cpp true` if type is an object, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_object()` for all JSON types. + + ```cpp + --8<-- "examples/is_object.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_object.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_primitive.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_primitive.md new file mode 100644 index 0000000..cf6cbbd --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_primitive.md @@ -0,0 +1,69 @@ +# nlohmann::basic_json::is_primitive + +```cpp +constexpr bool is_primitive() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON type is primitive (string, number, boolean, `#!json null`, +binary). + +## Return value + +`#!cpp true` if type is primitive (string, number, boolean, `#!json null`, or binary), `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +constexpr bool is_primitive() const noexcept +{ + return is_null() || is_string() || is_boolean() || is_number() || is_binary(); +} +``` + +## Notes + +The term *primitive* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259): + +> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and +> arrays). + +This library extends primitive types to binary types, because binary types are roughly comparable to strings. Hence, +`is_primitive()` returns `#!cpp true` for binary values. + +## Examples + +??? example + + The following code exemplifies `is_primitive()` for all JSON types. + + ```cpp + --8<-- "examples/is_primitive.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_primitive.output" + ``` + +## See also + +- [is_structured()](is_structured.md) returns whether JSON value is structured +- [is_null()](is_null.md) returns whether JSON value is `null` +- [is_string()](is_string.md) returns whether JSON value is a string +- [is_boolean()](is_boolean.md) returns whether JSON value is a boolean +- [is_number()](is_number.md) returns whether JSON value is a number +- [is_binary()](is_binary.md) returns whether JSON value is a binary array + +## Version history + +- Added in version 1.0.0. +- Extended to return `#!cpp true` for binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_string.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_string.md new file mode 100644 index 0000000..b82c924 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_string.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_string + +```cpp +constexpr bool is_string() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a string. + +## Return value + +`#!cpp true` if type is a string, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_string()` for all JSON types. + + ```cpp + --8<-- "examples/is_string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_string.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/is_structured.md b/json-develop/docs/mkdocs/docs/api/basic_json/is_structured.md new file mode 100644 index 0000000..f8fe4dc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/is_structured.md @@ -0,0 +1,63 @@ +# nlohmann::basic_json::is_structured + +```cpp +constexpr bool is_structured() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON type is structured (array or object). + +## Return value + +`#!cpp true` if type is structured (array or object), `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +constexpr bool is_primitive() const noexcept +{ + return is_array() || is_object(); +} +``` + +## Notes + +The term *structured* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259): + +> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and +> arrays). + +Note that though strings are containers in C++, they are treated as primitive values in JSON. + +## Examples + +??? example + + The following code exemplifies `is_structured()` for all JSON types. + + ```cpp + --8<-- "examples/is_structured.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_structured.output" + ``` + +## See also + +- [is_primitive()](is_primitive.md) returns whether JSON value is primitive +- [is_array()](is_array.md) returns whether value is an array +- [is_object()](is_object.md) returns whether value is an object + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/items.md b/json-develop/docs/mkdocs/docs/api/basic_json/items.md new file mode 100644 index 0000000..0b34ddc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/items.md @@ -0,0 +1,100 @@ +# nlohmann::basic_json::items + +```cpp +iteration_proxy items() noexcept; +iteration_proxy items() const noexcept; +``` + +This function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a +reference to the JSON values is returned, so there is no access to the underlying iterator. + +For loop without `items()` function: + +```cpp +for (auto it = j_object.begin(); it != j_object.end(); ++it) +{ + std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; +} +``` + +Range-based for loop without `items()` function: + +```cpp +for (auto it : j_object) +{ + // "it" is of type json::reference and has no key() member + std::cout << "value: " << it << '\n'; +} +``` + +Range-based for loop with `items()` function: + +```cpp +for (auto& el : j_object.items()) +{ + std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; +} +``` + +The `items()` function also allows using +[structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) (C++17): + +```cpp +for (auto& [key, val] : j_object.items()) +{ + std::cout << "key: " << key << ", value:" << val << '\n'; +} +``` + +## Return value + +iteration proxy object wrapping the current value with an interface to use in range-based for loops + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Constant. + +## Notes + +When iterating over an array, `key()` will return the index of the element as string (see example). For primitive types +(e.g., numbers), `key()` returns an empty string. + +!!! danger "Lifetime issues" + + Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See + for more information. + +## Examples + +??? example + + The following code shows an example for `items()`. + + ```cpp + --8<-- "examples/items.cpp" + ``` + + Output: + + ```json + --8<-- "examples/items.output" + ``` + +## Version history + +- Added `iterator_wrapper` in version 3.0.0. +- Added `items` and deprecated `iterator_wrapper` in version 3.1.0. +- Added structured binding support in version 3.5.0. + +!!! warning "Deprecation" + + This function replaces the static function `iterator_wrapper` which was introduced in version 1.0.0, but has been + deprecated in version 3.1.0. Function `iterator_wrapper` will be removed in version 4.0.0. Please replace all + occurrences of `#!cpp iterator_wrapper(j)` with `#!cpp j.items()`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/json_base_class_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/json_base_class_t.md new file mode 100644 index 0000000..7575204 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/json_base_class_t.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json::json_base_class_t + +```cpp +using json_base_class_t = detail::json_base_class; +``` + +The base class used to inject custom functionality into each instance of `basic_json`. +Examples of such functionality might be metadata, additional member functions (e.g., visitors), or other application-specific code. + +## Template parameters + +`CustomBaseClass` +: the base class to be added to `basic_json` + +## Notes + +#### Default type + +The default value for `CustomBaseClass` is `void`. In this case an +[empty base class](https://en.cppreference.com/w/cpp/language/ebo) is used and no additional functionality is injected. + +#### Limitations + +The type `CustomBaseClass` has to be a default-constructible class. +`basic_json` only supports copy/move construction/assignment if `CustomBaseClass` does so as well. + +## Examples + +??? example + + The following code shows how to inject custom data and methods for each node. + + ```cpp + --8<-- "examples/json_base_class_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_base_class_t.output" + ``` + +## Version history + +- Added in version 3.12.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/json_serializer.md b/json-develop/docs/mkdocs/docs/api/basic_json/json_serializer.md new file mode 100644 index 0000000..b8b67c5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/json_serializer.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::json_serializer + +```cpp +template +using json_serializer = JSONSerializer; +``` + +## Template parameters + +`T` +: type to convert; will be used in the `to_json`/`from_json` functions + +`SFINAE` +: type to add compile type checks via SFINAE; usually `#!cpp void` + +## Notes + +#### Default type + +The default values for `json_serializer` is [`adl_serializer`](../adl_serializer). + +## Examples + +??? example + + The example below shows how a conversion of a non-default-constructible type is implemented via a specialization of + the `adl_serializer`. + + ```cpp + --8<-- "examples/from_json__non_default_constructible.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_json__non_default_constructible.output" + ``` + +## Version history + +- Since version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/max_size.md b/json-develop/docs/mkdocs/docs/api/basic_json/max_size.md new file mode 100644 index 0000000..4c0c575 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/max_size.md @@ -0,0 +1,60 @@ +# nlohmann::basic_json::max_size + +```cpp +size_type max_size() const noexcept; +``` + +Returns the maximum number of elements a JSON value is able to hold due to system or library implementation limitations, +i.e. `std::distance(begin(), end())` for the JSON value. + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +|------------|-------------------------------------------| +| null | `0` (same as [`size()`](size.md)) | +| boolean | `1` (same as [`size()`](size.md)) | +| string | `1` (same as [`size()`](size.md)) | +| number | `1` (same as [`size()`](size.md)) | +| binary | `1` (same as [`size()`](size.md)) | +| object | result of function `object_t::max_size()` | +| array | result of function `array_t::max_size()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the +[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `max_size()` functions have +constant complexity. + +## Notes + +This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of +string elements the JSON value can store which is `1`. + +## Examples + +??? example + + The following code calls `max_size()` on the different value types. + + ```cpp + --8<-- "examples/max_size.cpp" + ``` + + Output: + + ```json + --8<-- "examples/max_size.output" + ``` + + Note the output is platform-dependent. + +## Version history + +- Added in version 1.0.0. +- Extended to return `1` for binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/merge_patch.md b/json-develop/docs/mkdocs/docs/api/basic_json/merge_patch.md new file mode 100644 index 0000000..1718c92 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/merge_patch.md @@ -0,0 +1,63 @@ +# nlohmann::basic_json::merge_patch + +```cpp +void merge_patch(const basic_json& apply_patch); +``` + +The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of +modifications to a target resource's content. This function applies a merge patch to the current JSON value. + +The function implements the following algorithm from Section 2 of +[RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): + +```python +define MergePatch(Target, Patch): + if Patch is an Object: + if Target is not an Object: + Target = {} // Ignore the contents and set it to an empty Object + for each Name/Value pair in Patch: + if Value is null: + if Name exists in Target: + remove the Name/Value pair from Target + else: + Target[Name] = MergePatch(Target[Name], Value) + return Target + else: + return Patch +``` + +Thereby, `Target` is the current object; that is, the patch is applied to the current value. + +## Parameters + +`apply_patch` (in) +: the patch to apply + +## Complexity + +Linear in the lengths of `apply_patch`. + +## Examples + +??? example + + The following code shows how a JSON Merge Patch is applied to a JSON document. + + ```cpp + --8<-- "examples/merge_patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/merge_patch.output" + ``` + +## See also + +- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) +- [patch](patch.md) apply a JSON patch + +## Version history + +- Added in version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/meta.md b/json-develop/docs/mkdocs/docs/api/basic_json/meta.md new file mode 100644 index 0000000..c584f9b --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/meta.md @@ -0,0 +1,56 @@ +# nlohmann::basic_json::meta + +```cpp +static basic_json meta(); +``` + +This function returns a JSON object with information about the library, including the version number and information on +the platform and compiler. + +## Return value + +JSON object holding version information + +| key | description | +|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). | +| `copyright` | The copyright line for the library as string. | +| `name` | The name of the library as string. | +| `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. | +| `url` | The URL of the project as string. | +| `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). | + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example output of the `meta()` function. + + ```cpp + --8<-- "examples/meta.cpp" + ``` + + Output: + + ```json + --8<-- "examples/meta.output" + ``` + + Note the output is platform-dependent. + +## See also + +- [**NLOHMANN_JSON_VERSION_MAJOR**/**NLOHMANN_JSON_VERSION_MINOR**/**NLOHMANN_JSON_VERSION_PATCH**](../macros/nlohmann_json_version_major.md) + \- library version information + +## Version history + +- Added in version 2.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/number_float_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/number_float_t.md new file mode 100644 index 0000000..50aa43b --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/number_float_t.md @@ -0,0 +1,70 @@ +# nlohmann::basic_json::number_float_t + +```cpp +using number_float_t = NumberFloatType; +``` + +The type used to store JSON numbers (floating-point). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: +> The representation of numbers is similar to that used in most programming languages. A number is represented in base +> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may +> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that +> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is +known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different +types, [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md) and `number_float_t` are +used. + +To store floating-point numbers in C++, a type is defined by the template parameter `NumberFloatType` which chooses the +type to use. + +## Notes + +#### Default type + +With the default values for `NumberFloatType` (`double`), the default value for `number_float_t` is `#!cpp double`. + +#### Default behavior + +- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in floating-point literals will be + ignored. Internally, the value will be stored as decimal number. For instance, the C++ floating-point literal `01.2` + will be serialized to `1.2`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `null`. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: +> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software +> that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good +> interoperability can be achieved by implementations that expect no more precision or range than these provide, in the +> sense that implementations will approximate JSON numbers within the expected precision. + +This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values +smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally +and be serialized to `null`. + +#### Storage + +Floating-point number values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `number_float_t` is by default, a typedef to `#!cpp double`. + + ```cpp + --8<-- "examples/number_float_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/number_float_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/number_integer_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/number_integer_t.md new file mode 100644 index 0000000..9bb3835 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/number_integer_t.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::number_integer_t + +```cpp +using number_integer_t = NumberIntegerType; +``` + +The type used to store JSON numbers (integers). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: +> The representation of numbers is similar to that used in most programming languages. A number is represented in base +> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may +> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that +> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is +known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different +types, `number_integer_t`, [`number_unsigned_t`](number_unsigned_t.md) and [`number_float_t`](number_float_t.md) are +used. + +To store integer numbers in C++, a type is defined by the template parameter `NumberIntegerType` which chooses the type +to use. + +## Notes + +#### Default type + +With the default values for `NumberIntegerType` (`std::int64_t`), the default value for `number_integer_t` is +`#!cpp std::int64_t`. + +#### Default behavior + +- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an + interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer + literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `null`. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and +the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of +range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers +will be automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: +> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are +> interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is +interoperable. + +#### Storage + +Integer number values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `number_integer_t` is by default, a typedef to `#!cpp std::int64_t`. + + ```cpp + --8<-- "examples/number_integer_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/number_integer_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md new file mode 100644 index 0000000..8a1540a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::number_unsigned_t + +```cpp +using number_unsigned_t = NumberUnsignedType; +``` + +The type used to store JSON numbers (unsigned). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: +> The representation of numbers is similar to that used in most programming languages. A number is represented in base +> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may +> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that +> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is +known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different +types, [`number_integer_t`](number_integer_t.md), `number_unsigned_t` and [`number_float_t`](number_float_t.md) are +used. + +To store unsigned integer numbers in C++, a type is defined by the template parameter `NumberUnsignedType` which chooses +the type to use. + +## Notes + +#### Default type + +With the default values for `NumberUnsignedType` (`std::uint64_t`), the default value for `number_unsigned_t` is +`#!cpp std::uint64_t`. + +#### Default behavior + +- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an + interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer + literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `null`. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and +the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow +when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored +as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: +> Note that when such software is used, numbers that are integers and are in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are +> interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange (when considered in conjunction with the `number_integer_t` type) of the exactly supported +range [0, UINT64_MAX], this class's integer type is interoperable. + +#### Storage + +Integer number values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `number_unsigned_t` is by default, a typedef to `#!cpp std::uint64_t`. + + ```cpp + --8<-- "examples/number_unsigned_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/number_unsigned_t.output" + ``` + +## Version history + +- Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/object.md b/json-develop/docs/mkdocs/docs/api/basic_json/object.md new file mode 100644 index 0000000..9bdbddb --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/object.md @@ -0,0 +1,63 @@ +# nlohmann::basic_json::object + +```cpp +static basic_json object(initializer_list_t init = {}); +``` + +Creates a JSON object value from a given initializer list. The initializer lists elements must be pairs, and their first +elements must be strings. If the initializer list is empty, the empty object `#!json {}` is created. + +## Parameters + +`init` (in) +: initializer list with JSON values to create an object from (optional) + +## Return value + +JSON object value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `init` is not a list of pairs whose +first elements are strings. In this case, no object can be created. When such a value is passed to +`basic_json(initializer_list_t, bool, value_t)`, an array would have been created from the passed initializer list +`init`. See example below. + +## Complexity + +Linear in the size of `init`. + +## Notes + +This function is only added for symmetry reasons. In contrast to the related function `array(initializer_list_t)`, there +are no cases which can only be expressed by this function. That is, any initializer list `init` can also be passed to +the initializer list constructor `basic_json(initializer_list_t, bool, value_t)`. + +## Examples + +??? example + + The following code shows an example for the `object` function. + + ```cpp + --8<-- "examples/object.cpp" + ``` + + Output: + + ```json + --8<-- "examples/object.output" + ``` + +## See also + +- [`basic_json(initializer_list_t)`](basic_json.md) - create a JSON value from an initializer list +- [`array`](array.md) - create a JSON array value from an initializer list + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/object_comparator_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/object_comparator_t.md new file mode 100644 index 0000000..d41b982 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/object_comparator_t.md @@ -0,0 +1,32 @@ +# nlohmann::basic_json::object_comparator_t + +```cpp +using object_comparator_t = typename object_t::key_compare; +// or +using object_comparator_t = default_object_comparator_t; +``` + +The comparator used by [`object_t`](object_t.md). Defined as `#!cpp typename object_t::key_compare` if available, +and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise. + +## Examples + +??? example + + The example below demonstrates the used object comparator. + + ```cpp + --8<-- "examples/object_comparator_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/object_comparator_t.output" + ``` + +## Version history + +- Added in version 3.0.0. +- Changed to be conditionally defined as `#!cpp typename object_t::key_compare` or `default_object_comparator_t` in + version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/object_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/object_t.md new file mode 100644 index 0000000..39f68b0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/object_t.md @@ -0,0 +1,114 @@ +# nlohmann::basic_json::object_t + +```cpp +using object_t = ObjectType>>; +``` + +The type used to store JSON objects. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: +> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a +> string, number, boolean, null, object, or array. + +To store objects in C++, a type is defined by the template parameters described below. + +## Template parameters + +`ObjectType` +: the container to store objects (e.g., `std::map` or `std::unordered_map`) + +`StringType` +: the type of the keys or names (e.g., `std::string`). The comparison function `std::less` is used to + order elements inside the container. + +`AllocatorType` +: the allocator to use for objects (e.g., `std::allocator`) + +## Notes + +#### Default type + +With the default values for `ObjectType` (`std::map`), `StringType` (`std::string`), and `AllocatorType` +(`std::allocator`), the default value for `object_t` is: + +```cpp +// until C++14 +std::map< + std::string, // key_type + basic_json, // value_type + std::less, // key_compare + std::allocator> // allocator_type +> + +// since C++14 +std::map< + std::string, // key_type + basic_json, // value_type + std::less<>, // key_compare + std::allocator> // allocator_type +> +``` + +See [`default_object_comparator_t`](default_object_comparator_t.md) for more information. + +#### Behavior + +The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following +behavior: + +- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that + object will agree on the name-value mappings. +- When the names within an object are not unique, it is unspecified which one of the values for a given key will be + chosen. For instance, `#!json {"key": 2, "key": 1}` could be equal to either `#!json {"key": 1}` or + `#!json {"key": 2}`. +- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see + [`dump`](dump.md)) in this order. For instance, `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be stored + and serialized as `#!json {"a": 2, "b": 1}`. +- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense + that they will not be affected by these differences. For instance, `#!json {"b": 1, "a": 2}` and + `#!json {"a": 2, "b": 1}` will be treated as equal. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the maximum depth of nesting. + +In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be +introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the +[`max_size`](max_size.md) function of a JSON object. + +#### Storage + +Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type +`object_t*` must be dereferenced. + +#### Object key order + +The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may +return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in +alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to +[RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON +objects. + +## Examples + +??? example + + The following code shows that `object_t` is by default, a typedef to `#!cpp std::map`. + + ```cpp + --8<-- "examples/object_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/object_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator+=.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator+=.md new file mode 100644 index 0000000..dc5f2ec --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator+=.md @@ -0,0 +1,110 @@ +# nlohmann::basic_json::operator+= + +```cpp +// (1) +reference operator+=(basic_json&& val); +reference operator+=(const basic_json& val); + +// (2) +reference operator+=(const typename object_t::value_type& val); + +// (3) +reference operator+=(initializer_list_t init); +``` + +1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an + empty array is created before appending `val`. + +2. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object + is created before inserting `val`. + +3. This function allows using `operator+=` with an initializer list. In case + + 1. the current value is an object, + 2. the initializer list `init` contains only two elements, and + 3. the first element of `init` is a string, + + `init` is converted into an object element and added using `operator+=(const typename object_t::value_type&)`. + Otherwise, `init` is converted to a JSON value and added using `operator+=(basic_json&&)`. + +## Parameters + +`val` (in) +: the value to add to the JSON array/object + +`init` (in) +: an initializer list + +## Return value + +`#!cpp *this` + +## Exceptions + +All functions can throw the following exception: + - Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON array or null; example: `"cannot use operator+=() with number"` + +## Complexity + +1. Amortized constant. +2. Logarithmic in the size of the container, O(log(`size()`)). +3. Linear in the size of the initializer list `init`. + +## Notes + +(3) This function is required to resolve an ambiguous overload error, because pairs like `{"key", "value"}` can be both +interpreted as `object_t::value_type` or `std::initializer_list`, see +[#235](https://github.com/nlohmann/json/issues/235) for more information. + +## Examples + +??? example "Example: (1) add element to array" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value + was silently converted to a JSON array. + + ```cpp + --8<-- "examples/push_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back.output" + ``` + +??? example "Example: (2) add element to object" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value + was silently converted to a JSON object. + + ```cpp + --8<-- "examples/push_back__object_t__value.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__object_t__value.output" + ``` + +??? example "Example: (3) add to object from initializer list" + + The example shows how initializer lists are treated as objects when possible. + + ```cpp + --8<-- "examples/push_back__initializer_list.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__initializer_list.output" + ``` + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +2. Since version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator=.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator=.md new file mode 100644 index 0000000..4e0b914 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator=.md @@ -0,0 +1,43 @@ +# nlohmann::basic_json::operator= + +```cpp +basic_json& operator=(basic_json other) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value +); +``` + +Copy assignment operator. Copies a JSON value via the "copy and swap" strategy: It is expressed in terms of the copy +constructor, destructor, and the `swap()` member function. + +## Parameters + +`other` (in) +: value to copy from + +## Complexity + +Linear. + +## Examples + +??? example + + The code below shows and example for the copy assignment. It creates a copy of value `a` which is then swapped with + `b`. Finally, the copy of `a` (which is the null value after the swap) is destroyed. + + ```cpp + --8<-- "examples/basic_json__copyassignment.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__copyassignment.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator[].md b/json-develop/docs/mkdocs/docs/api/basic_json/operator[].md new file mode 100644 index 0000000..51dd858 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator[].md @@ -0,0 +1,241 @@ +# nlohmann::basic_json::operator[] + +```cpp +// (1) +reference operator[](size_type idx); +const_reference operator[](size_type idx) const; + +// (2) +reference operator[](typename object_t::key_type key); +const_reference operator[](const typename object_t::key_type& key) const; + +// (3) +template +reference operator[](KeyType&& key); +template +const_reference operator[](KeyType&& key) const; + +// (4) +reference operator[](const json_pointer& ptr); +const_reference operator[](const json_pointer& ptr) const; +``` + +1. Returns a reference to the array element at specified location `idx`. +2. Returns a reference to the object element with specified key `key`. The non-const qualified overload takes the key by + value. +3. See 2. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. +4. Returns a reference to the element with specified JSON pointer `ptr`. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`idx` (in) +: index of the element to access + +`key` (in) +: object key of the element to access + +`ptr` (in) +: JSON pointer to the desired element + +## Return value + +1. (const) reference to the element at index `idx` +2. (const) reference to the element at key `key` +3. (const) reference to the element at key `key` +4. (const) reference to the element pointed to by `ptr` + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array + or null; in that case, using the `[]` operator with an index makes no sense. +2. The function can throw the following exceptions: + - Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object + or null; in that case, using the `[]` operator with a key makes no sense. +3. See 2. +4. The function can throw the following exceptions: + - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed + JSON pointer `ptr` begins with '0'. + - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed + JSON pointer `ptr` is not a number. + - Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index '-' is used + in the passed JSON pointer `ptr` for the const version. + - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if the JSON pointer `ptr` can + not be resolved. + +## Complexity + +1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`. +2. Logarithmic in the size of the container. +3. Logarithmic in the size of the container. +4. Logarithmic in the size of the container. + +## Notes + +!!! danger "Undefined behavior and runtime assertions" + + 1. If the element with key `idx` does not exist, the behavior is undefined. + 2. If the element with key `key` does not exist, the behavior is undefined and is **guarded by a + [runtime assertion](../../features/assertions.md)**! + +1. The non-const version may add values: If `idx` is beyond the range of the array (i.e., `idx >= size()`), then the + array is silently filled up with `#!json null` values to make `idx` a valid reference to the last stored element. In + case the value was `#!json null` before, it is converted to an array. + +2. If `key` is not found in the object, then it is silently added to the object and filled with a `#!json null` value to + make `key` a valid reference. In case the value was `#!json null` before, it is converted to an object. + +3. See 2. + +4. `null` values are created in arrays and objects if necessary. + + In particular: + + - If the JSON pointer points to an object key that does not exist, it is created and filled with a `#!json null` + value before a reference to it is returned. + - If the JSON pointer points to an array index that does not exist, it is created and filled with a `#!json null` + value before a reference to it is returned. All indices between the current maximum and the given index are also + filled with `#!json null`. + - The special value `-` is treated as a synonym for the index past the end. + +## Examples + +??? example "Example: (1) access specified array element" + + The example below shows how array elements can be read and written using `[]` operator. Note the addition of + `#!json null` values. + + ```cpp + --8<-- "examples/operator_array__size_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__size_type.output" + ``` + +??? example "Example: (1) access specified array element (const)" + + The example below shows how array elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__size_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__size_type_const.output" + ``` + +??? example "Example: (2) access specified object element" + + The example below shows how object elements can be read and written using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__object_t_key_type.output" + ``` + +??? example "Example: (2) access specified object element (const)" + + The example below shows how object elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__object_t_key_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__object_t_key_type_const.output" + ``` + +??? example "Example: (3) access specified object element using string_view" + + The example below shows how object elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__keytype.c++17.output" + ``` + +??? example "Example: (3) access specified object element using string_view (const)" + + The example below shows how object elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__keytype_const.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__keytype_const.c++17.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer" + + The example below shows how values can be read and written using JSON Pointers. + + ```cpp + --8<-- "examples/operator_array__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__json_pointer.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer (const)" + + The example below shows how values can be read using JSON Pointers. + + ```cpp + --8<-- "examples/operator_array__json_pointer_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__json_pointer_const.output" + ``` + +## See also + +- documentation on [unchecked access](../../features/element_access/unchecked_access.md) +- documentation on [runtime assertions](../../features/assertions.md) +- see [`at`](at.md) for access by reference with range checking +- see [`value`](value.md) for access with default value + +## Version history + +1. Added in version 1.0.0. +2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3) + in version 3.11.0. +3. Added in version 3.11.0. +4. Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_ValueType.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_ValueType.md new file mode 100644 index 0000000..bf38a3d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_ValueType.md @@ -0,0 +1,82 @@ +# nlohmann::basic_json::operator ValueType + +```cpp +template +JSON_EXPLICIT operator ValueType() const; +``` + +Implicit type conversion between the JSON value and a compatible value. The call is realized by calling +[`get()`](get.md). See [Notes](#notes) for the meaning of `JSON_EXPLICIT`. + +## Template parameters + +`ValueType` +: the value type to return + +## Return value + +copy of the JSON value, converted to `ValueType` + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +!!! note "Definition of `JSON_EXPLICIT`" + + By default `JSON_EXPLICIT` is defined to the empty string, so the signature is: + + ```cpp + template + operator ValueType() const; + ``` + + If [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) is set to `0`, + `JSON_EXPLICIT` is defined to `#!cpp explicit`: + + ```cpp + template + explicit operator ValueType() const; + ``` + + That is, implicit conversions can be switched off by defining + [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0`. + +!!! info "Future behavior change" + + Implicit conversions will be switched off by default in the next major release of the library. That is, + `JSON_EXPLICIT` will be set to `#!cpp explicit` by default. + + You can prepare existing code by already defining + [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0` and replace any implicit + conversions with calls to [`get`](../basic_json/get.md). + +## Examples + +??? example + + The example below shows several conversions from JSON values to other types. There are a few things to note: (1) + Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard + `std::vector`, (3) A JSON object can be converted to C++ associative containers such as + `std::unordered_map`. + + ```cpp + --8<-- "examples/operator__ValueType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__ValueType.output" + ``` + +## Version history + +- Since version 1.0.0. +- Macros `JSON_EXPLICIT`/[`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) added + in version 3.9.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_eq.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_eq.md new file mode 100644 index 0000000..a2ce615 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_eq.md @@ -0,0 +1,168 @@ +# nlohmann::basic_json::operator== + +```cpp +// until C++20 +bool operator==(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator==(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator==(ScalarType lhs, const const_reference rhs) noexcept; // (2) + +// since C++20 +class basic_json { + bool operator==(const_reference rhs) const noexcept; // (1) + + template + bool operator==(ScalarType rhs) const noexcept; // (2) +}; +``` + +1. Compares two JSON values for equality according to the following rules: + - Two JSON values are equal if (1) neither value is discarded, or (2) they are of the same type and their stored + values are the same according to their respective `operator==`. + - Integer and floating-point numbers are automatically converted before comparison. + +2. Compares a JSON value and a scalar or a scalar and a JSON value for equality by converting the + scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are equal + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing special values" + + - `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + - JSON `#!cpp null` values are all equal. + - Discarded values never compare equal to themselves. + +!!! note "Comparing floating-point numbers" + + Floating-point numbers inside JSON values numbers are compared with `json::number_float_t::operator==` which is + `double::operator==` by default. To compare floating-point while respecting an epsilon, an alternative + [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) + could be used, for instance + + ```cpp + template::value, T>::type> + inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept + { + return std::abs(a - b) <= epsilon; + } + ``` + + Or you can self-defined operator equal function like this: + + ```cpp + bool my_equal(const_reference lhs, const_reference rhs) + { + const auto lhs_type lhs.type(); + const auto rhs_type rhs.type(); + if (lhs_type == rhs_type) + { + switch(lhs_type) + // self_defined case + case value_t::number_float: + return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); + // other cases remain the same with the original + ... + } + ... + } + ``` + +!!! note "Comparing different `basic_json` specializations" + + Comparing different `basic_json` specializations can have surprising effects. For instance, the result of comparing + the JSON objects + + ```json + { + "version": 1, + "type": "integer" + } + ``` + + and + + ```json + { + "type": "integer", + "version": 1 + } + ``` + + depends on whether [`nlohmann::json`](../json.md) or [`nlohmann::ordered_json`](../ordered_json.md) is used: + + ```cpp + --8<-- "examples/operator__equal__specializations.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__equal__specializations.output" + ``` + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__equal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__equal.output" + ``` + +??? example + + The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`). + + ```cpp + --8<-- "examples/operator__equal__nullptr_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__equal__nullptr_t.output" + ``` + +## Version history + +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. +2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_ge.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_ge.md new file mode 100644 index 0000000..d4e2fb4 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_ge.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::operator>= + +```cpp +// until C++20 +bool operator>=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator>=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator>=(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is greater than or equal to another JSON value `rhs` according to the following + rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either operand is `NaN` and + the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(lhs < rhs)` (see [**operator<**](operator_lt.md)). + +2. Compares whether a JSON value is greater than or equal to a scalar or a scalar is greater than or equal to a JSON + value by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is less than or equal to `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__greaterequal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__greaterequal.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_gt.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_gt.md new file mode 100644 index 0000000..9516656 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_gt.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::operator> + +```cpp +// until C++20 +bool operator>(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator>(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator>(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is greater than another JSON value `rhs` according to the + following rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either + operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(lhs <= rhs)` (see [**operator<=**](operator_le.md)). + +2. Compares wether a JSON value is greater than a scalar or a scalar is greater than a JSON value by + converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is greater than `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__greater.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__greater.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_le.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_le.md new file mode 100644 index 0000000..7b648e0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_le.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::operator<= + +```cpp +// until C++20 +bool operator<=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator<=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator<=(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is less than or equal to another JSON value `rhs` + according to the following rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either + operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(rhs < lhs)` (see [**operator<**](operator_lt.md)). + +1. Compares wether a JSON value is less than or equal to a scalar or a scalar is less than or equal + to a JSON value by converting the scalar to a JSON value and comparing both JSON values according + to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is less than or equal to `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__lessequal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__lessequal.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_lt.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_lt.md new file mode 100644 index 0000000..b5d191e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_lt.md @@ -0,0 +1,96 @@ +# nlohmann::basic_json::operator< + +```cpp +// until C++20 +bool operator<(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator<(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator<(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is less than another JSON value `rhs` according to the + following rules: + - If either operand is discarded, the comparison yields `#!cpp false`. + - If both operands have the same type, the values are compared using their respective `operator<`. + - Integer and floating-point numbers are automatically converted before comparison. + - In case `lhs` and `rhs` have different types, the values are ignored and the order of the types + is considered, which is: + 1. null + 2. boolean + 3. number (all types) + 4. object + 5. array + 6. string + 7. binary + For instance, any boolean value is considered less than any string. + +2. Compares wether a JSON value is less than a scalar or a scalar is less than a JSON value by converting + the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is less than `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__less.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__less.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_ne.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_ne.md new file mode 100644 index 0000000..982a067 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_ne.md @@ -0,0 +1,98 @@ +# nlohmann::basic_json::operator!= + +```cpp +// until C++20 +bool operator!=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator!=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator!=(ScalarType lhs, const const_reference rhs) noexcept; // (2) + +// since C++20 +class basic_json { + bool operator!=(const_reference rhs) const noexcept; // (1) + + template + bool operator!=(ScalarType rhs) const noexcept; // (2) +}; +``` + +1. Compares two JSON values for inequality according to the following rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either operand is `NaN` and + the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(lhs == rhs)` (until C++20) or `#!cpp !(*this == rhs)` (since C++20). + +2. Compares a JSON value and a scalar or a scalar and a JSON value for inequality by converting the scalar to a JSON + value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are not equal + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__notequal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__notequal.output" + ``` + +??? example + + The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`). + + ```cpp + --8<-- "examples/operator__notequal__nullptr_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__notequal__nullptr_t.output" + ``` + +## Version history + +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. +2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_spaceship.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_spaceship.md new file mode 100644 index 0000000..9e91d0d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_spaceship.md @@ -0,0 +1,100 @@ +# nlohmann::basic_json::operator<=> + +```cpp +// since C++20 +class basic_json { + std::partial_ordering operator<=>(const_reference rhs) const noexcept; // (1) + + template + std::partial_ordering operator<=>(const ScalarType rhs) const noexcept; // (2) +}; +``` + +1. 3-way compares two JSON values producing a result of type `std::partial_ordering` according to the following rules: + - Two JSON values compare with a result of `std::partial_ordering::unordered` if either value is discarded. + - If both JSON values are of the same type, the result is produced by 3-way comparing their stored values using + their respective `operator<=>`. + - Integer and floating-point numbers are converted to their common type and then 3-way compared using their + respective `operator<=>`. + For instance, comparing an integer and a floating-point value will 3-way compare the first value converted to + floating-point with the second value. + - Otherwise, yields a result by comparing the type (see [`value_t`](value_t.md)). + +2. 3-way compares a JSON value and a scalar or a scalar and a JSON value by converting the scalar to a JSON value and + 3-way comparing both JSON values (see 1). + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`rhs` (in) +: second value to consider + +## Return value + +the `std::partial_ordering` of the 3-way comparison of `*this` and `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + - `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `std::partial_ordering::unordered`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +## Examples + +??? example "Example: (1) comparing JSON values" + + The example demonstrates comparing several JSON values. + + ```cpp + --8<-- "examples/operator_spaceship__const_reference.c++20.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_spaceship__const_reference.c++20.output" + ``` + +??? example "Example: (2) comparing JSON values and scalars" + + The example demonstrates comparing several JSON values and scalars. + + ```cpp + --8<-- "examples/operator_spaceship__scalartype.c++20.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_spaceship__scalartype.c++20.output" + ``` + +## See also + +- [**operator==**](operator_eq.md) - comparison: equal +- [**operator!=**](operator_ne.md) - comparison: not equal +- [**operator<**](operator_lt.md) - comparison: less than +- [**operator<=**](operator_le.md) - comparison: less than or equal +- [**operator>**](operator_gt.md) - comparison: greater than +- [**operator>=**](operator_ge.md) - comparison: greater than or equal + +## Version history + +1. Added in version 3.11.0. +2. Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/operator_value_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/operator_value_t.md new file mode 100644 index 0000000..0f08f42 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/operator_value_t.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::operator value_t + +```cpp +constexpr operator value_t() const noexcept; +``` + +Return the type of the JSON value as a value from the [`value_t`](value_t.md) enumeration. + +## Return value + +the type of the JSON value + +| Value type | return value | +|---------------------------|----------------------------| +| `#!json null` | `value_t::null` | +| boolean | `value_t::boolean` | +| string | `value_t::string` | +| number (integer) | `value_t::number_integer` | +| number (unsigned integer) | `value_t::number_unsigned` | +| number (floating-point) | `value_t::number_float` | +| object | `value_t::object` | +| array | `value_t::array` | +| binary | `value_t::binary` | +| discarded | `value_t::discarded` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `operator value_t()` for all JSON types. + + ```cpp + --8<-- "examples/operator__value_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__value_t.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/other_error.md b/json-develop/docs/mkdocs/docs/api/basic_json/other_error.md new file mode 100644 index 0000000..9a83340 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/other_error.md @@ -0,0 +1,67 @@ +# nlohmann::basic_json::other_error + +```cpp +class other_error : public exception; +``` + +This exception is thrown in case of errors that cannot be classified with the other exception types. + +Exceptions have ids 5xx (see [list of other errors](../../home/exceptions.md#further-exceptions)). + +```plantuml +std::exception <|-- basic_json::exception +basic_json::exception <|-- basic_json::parse_error +basic_json::exception <|-- basic_json::invalid_iterator +basic_json::exception <|-- basic_json::type_error +basic_json::exception <|-- basic_json::out_of_range +basic_json::exception <|-- basic_json::other_error + +interface std::exception {} + +class basic_json::exception { + + const int id + + const char* what() const +} + +class basic_json::parse_error { + + const std::size_t byte +} + +class basic_json::other_error #FFFF00 {} +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `other_error` exception can be caught. + + ```cpp + --8<-- "examples/other_error.cpp" + ``` + + Output: + + ```json + --8<-- "examples/other_error.output" + ``` + +## See also + +- [List of other errors](../../home/exceptions.md#further-exceptions) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range + +## Version history + +- Since version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/out_of_range.md b/json-develop/docs/mkdocs/docs/api/basic_json/out_of_range.md new file mode 100644 index 0000000..6c1f0df --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/out_of_range.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::out_of_range + +```cpp +class out_of_range : public exception; +``` + +This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for +instance in case of array indices or nonexisting object keys. + +Exceptions have ids 4xx (see [list of out-of-range errors](../../home/exceptions.md#out-of-range)). + +```plantuml +std::exception <|-- basic_json::exception +basic_json::exception <|-- basic_json::parse_error +basic_json::exception <|-- basic_json::invalid_iterator +basic_json::exception <|-- basic_json::type_error +basic_json::exception <|-- basic_json::out_of_range +basic_json::exception <|-- basic_json::other_error + +interface std::exception {} + +class basic_json::exception { + + const int id + + const char* what() const +} + +class basic_json::parse_error { + + const std::size_t byte +} + +class basic_json::out_of_range #FFFF00 {} +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `out_of_range` exception can be caught. + + ```cpp + --8<-- "examples/out_of_range.cpp" + ``` + + Output: + + ```json + --8<-- "examples/out_of_range.output" + ``` + +## See also + +- [List of out-of-range errors](../../home/exceptions.md#out-of-range) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/parse.md b/json-develop/docs/mkdocs/docs/api/basic_json/parse.md new file mode 100644 index 0000000..49838ad --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/parse.md @@ -0,0 +1,214 @@ +# nlohmann::basic_json::parse + +```cpp +// (1) +template +static basic_json parse(InputType&& i, + const parser_callback_t cb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false); + +// (2) +template +static basic_json parse(IteratorType first, IteratorType last, + const parser_callback_t cb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false); +``` + +1. Deserialize from a compatible input. +2. Deserialize from a pair of character iterators + + The `value_type` of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted + respectively as UTF-8, UTF-16 and UTF-32. + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer (must not be null) + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - a `std::string` + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type, for instance. + + - a pair of `std::string::iterator` or `std::vector::iterator` + - a pair of pointers such as `ptr` and `ptr + len` + +## Parameters + +`i` (in) +: Input to parse from. + +`cb` (in) +: a parser callback function of type [`parser_callback_t`](parser_callback_t.md) which is used to control the + deserialization by filtering unwanted values (optional) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to start of character range + +`last` (in) +: iterator to end of character range + +## Return value + +Deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token. +- Throws [`parse_error.102`](../../home/exceptions.md#jsonexceptionparse_error102) if to_unicode fails or surrogate + error. +- Throws [`parse_error.103`](../../home/exceptions.md#jsonexceptionparse_error103) if to_unicode fails. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser +callback function `cb` or reading from (1) the input `i` or (2) the iterator range [`first`, `last`] has a +super-linear complexity. + +## Notes + +(1) A UTF-8 byte order mark is silently ignored. + +!!! danger "Runtime assertion" + + The precondition that a passed `#!cpp FILE` pointer must not be null is enforced with a + [runtime assertion](../../features/assertions.md). + +## Examples + +??? example "Parsing from a character array" + + The example below demonstrates the `parse()` function reading from an array. + + ```cpp + --8<-- "examples/parse__array__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__array__parser_callback_t.output" + ``` + +??? example "Parsing from a string" + + The example below demonstrates the `parse()` function with and without callback function. + + ```cpp + --8<-- "examples/parse__string__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__string__parser_callback_t.output" + ``` + +??? example "Parsing from an input stream" + + The example below demonstrates the `parse()` function with and without callback function. + + ```cpp + --8<-- "examples/parse__istream__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__istream__parser_callback_t.output" + ``` + +??? example "Parsing from a contiguous container" + + The example below demonstrates the `parse()` function reading from a contiguous container. + + ```cpp + --8<-- "examples/parse__contiguouscontainer__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__contiguouscontainer__parser_callback_t.output" + ``` + +??? example "Parsing from a non null-terminated string" + + The example below demonstrates the `parse()` function reading from a string that is not null-terminated. + + ```cpp + --8<-- "examples/parse__pointers.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__pointers.output" + ``` + +??? example "Parsing from an iterator pair" + + The example below demonstrates the `parse()` function reading from an iterator pair. + + ```cpp + --8<-- "examples/parse__iterator_pair.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__iterator_pair.output" + ``` + +??? example "Effect of `allow_exceptions` parameter" + + The example below demonstrates the effect of the `allow_exceptions` parameter in the ´parse()` function. + + ```cpp + --8<-- "examples/parse__allow_exceptions.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__allow_exceptions.output" + ``` + +## See also + +- [accept](accept.md) - check if the input is valid JSON +- [operator>>](../operator_gtgt.md) - deserialize from stream + +## Version history + +- Added in version 1.0.0. +- Overload for contiguous containers (1) added in version 2.0.3. +- Ignoring comments via `ignore_comments` added in version 3.9.0. + +!!! warning "Deprecation" + + Overload (2) replaces calls to `parse` with a pair of iterators as their first parameter which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp parse({ptr, ptr+len}, ...);` with `#!cpp parse(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/parse_error.md b/json-develop/docs/mkdocs/docs/api/basic_json/parse_error.md new file mode 100644 index 0000000..af3e1f0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/parse_error.md @@ -0,0 +1,74 @@ +# nlohmann::basic_json::parse_error + +```cpp +class parse_error : public exception; +``` + +This exception is thrown by the library when a parse error occurs. Parse errors can occur during the deserialization of +JSON text, BSON, CBOR, MessagePack, UBJSON, as well as when using JSON Patch. + +Member `byte` holds the byte index of the last read character in the input file (see note below). + +Exceptions have ids 1xx (see [list of parse errors](../../home/exceptions.md#parse-errors)). + +```plantuml +std::exception <|-- basic_json::exception +basic_json::exception <|-- basic_json::parse_error +basic_json::exception <|-- basic_json::invalid_iterator +basic_json::exception <|-- basic_json::type_error +basic_json::exception <|-- basic_json::out_of_range +basic_json::exception <|-- basic_json::other_error + +interface std::exception {} + +class basic_json::exception { + + const int id + + const char* what() const +} + +class basic_json::parse_error #FFFF00 { + + const std::size_t byte +} +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception +- **byte** - byte index of the parse error + +## Notes + +For an input with $n$ bytes, 1 is the index of the first character and $n+1$ is the index of the terminating null byte +or the end of file. This also holds true when reading a byte vector for binary formats. + +## Examples + +??? example + + The following code shows how a `parse_error` exception can be caught. + + ```cpp + --8<-- "examples/parse_error.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse_error.output" + ``` + +## See also + +- [List of parse errors](../../home/exceptions.md#parse-errors) +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/parse_event_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/parse_event_t.md new file mode 100644 index 0000000..1a7c390 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/parse_event_t.md @@ -0,0 +1,29 @@ +# nlohmann::basic_json::parse_event_t + +```cpp +enum class parse_event_t : std::uint8_t { + object_start, + object_end, + array_start, + array_end, + key, + value +}; +``` + +The parser callback distinguishes the following events: + +- `object_start`: the parser read `{` and started to process a JSON object +- `key`: the parser read a key of a value in an object +- `object_end`: the parser read `}` and finished processing a JSON object +- `array_start`: the parser read `[` and started to process a JSON array +- `array_end`: the parser read `]` and finished processing a JSON array +- `value`: the parser finished reading a JSON value + +## Examples + +![Example when certain parse events are triggered](../../images/callback_events.png) + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/parser_callback_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/parser_callback_t.md new file mode 100644 index 0000000..e10402e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/parser_callback_t.md @@ -0,0 +1,73 @@ +# nlohmann::basic_json::parser_callback_t + +```cpp +template +using parser_callback_t = + std::function; +``` + +With a parser callback function, the result of parsing a JSON text can be influenced. When passed to +[`parse`](parse.md), it is called on certain events (passed as [`parse_event_t`](parse_event_t.md) via parameter +`event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the callback function +is a boolean indicating whether the element that emitted the callback shall be kept or not. + +We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following +table describes the values of the parameters `depth`, `event`, and `parsed`. + +| parameter `event` | description | parameter `depth` | parameter `parsed` | +|-------------------------------|-----------------------------------------------------------|-------------------------------------------|----------------------------------| +| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded | +| `parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key | +| `parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object | +| `parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded | +| `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | +| `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | + +![Example when certain parse events are triggered](../../images/callback_events.png) + +Discarding a value (i.e., returning `#!cpp false`) has different effects depending on the context in which function was +called: + +- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never + read. +- In case a value outside a structured type is skipped, it is replaced with `null`. This case happens if the top-level + element is skipped. + +## Parameters + +`depth` (in) +: the depth of the recursion during parsing + +`event` (in) +: an event of type [`parse_event_t`](parse_event_t.md) indicating the context in + the callback function has been called + +`parsed` (in, out) +: the current intermediate parse result; note that + writing to this value has no effect for `parse_event_t::key` events + +## Return value + +Whether the JSON value which called the function during parsing should be kept (`#!cpp true`) or not (`#!cpp false`). In +the latter case, it is either skipped completely or replaced by an empty discarded object. + +## Examples + +??? example + + The example below demonstrates the `parse()` function with + and without callback function. + + ```cpp + --8<-- "examples/parse__string__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__string__parser_callback_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/patch.md b/json-develop/docs/mkdocs/docs/api/basic_json/patch.md new file mode 100644 index 0000000..deec474 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/patch.md @@ -0,0 +1,73 @@ +# nlohmann::basic_json::patch + +```cpp +basic_json patch(const basic_json& json_patch) const; +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to +a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from +the patch. + +## Parameters + +`json_patch` (in) +: JSON patch document + +## Return value + +patched document + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of + an array of objects. +- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., + mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch + could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent + ("add", "remove", "move") +- Throws [`out_of_range.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was + unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is +affected by the patch, the complexity can usually be neglected. + +## Notes + +The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception +is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value. + +## Examples + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [patch_inplace](patch_inplace.md) applies a JSON Patch without creating a copy of the document +- [merge_patch](merge_patch.md) applies a JSON Merge Patch + +## Version history + +- Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/patch_inplace.md b/json-develop/docs/mkdocs/docs/api/basic_json/patch_inplace.md new file mode 100644 index 0000000..e8fd176 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/patch_inplace.md @@ -0,0 +1,70 @@ +# nlohmann::basic_json::patch_inplace + +```cpp +void patch_inplace(const basic_json& json_patch) const; +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to +a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from +the patch. This function applies a JSON patch in place and returns void. + +## Parameters + +`json_patch` (in) +: JSON patch document + +## Exception safety + +No guarantees, value may be corrupted by an unsuccessful patch operation. + +## Exceptions + +- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of + an array of objects. +- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., + mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch + could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent + ("add", "remove", "move") +- Throws [`out_of_range.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was + unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is +affected by the patch, the complexity can usually be neglected. + +## Notes + +Unlike [`patch`](patch.md), `patch_inplace` applies the operation "in place" and no copy of the JSON value is created. +That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the +function throws an exception. + +## Examples + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch_inplace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch_inplace.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [patch](patch.md) applies a JSON Merge Patch +- [merge_patch](merge_patch.md) applies a JSON Merge Patch + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/push_back.md b/json-develop/docs/mkdocs/docs/api/basic_json/push_back.md new file mode 100644 index 0000000..5c7d20d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/push_back.md @@ -0,0 +1,106 @@ +# nlohmann::basic_json::push_back + +```cpp +// (1) +void push_back(basic_json&& val); +void push_back(const basic_json& val); + +// (2) +void push_back(const typename object_t::value_type& val); + +// (3) +void push_back(initializer_list_t init); +``` + +1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an + empty array is created before appending `val`. + +2. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object + is created before inserting `val`. + +3. This function allows using `push_back` with an initializer list. In case + + 1. the current value is an object, + 2. the initializer list `init` contains only two elements, and + 3. the first element of `init` is a string, + + `init` is converted into an object element and added using `push_back(const typename object_t::value_type&)`. + Otherwise, `init` is converted to a JSON value and added using `push_back(basic_json&&)`. + +## Parameters + +`val` (in) +: the value to add to the JSON array/object + +`init` (in) +: an initializer list + +## Exceptions + +All functions can throw the following exception: + - Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON array or null; example: `"cannot use push_back() with number"` + +## Complexity + +1. Amortized constant. +2. Logarithmic in the size of the container, O(log(`size()`)). +3. Linear in the size of the initializer list `init`. + +## Notes + +(3) This function is required to resolve an ambiguous overload error, because pairs like `{"key", "value"}` can be both + interpreted as `object_t::value_type` or `std::initializer_list`, see + [#235](https://github.com/nlohmann/json/issues/235) for more information. + +## Examples + +??? example "Example: (1) add element to array" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value + was silently converted to a JSON array. + + ```cpp + --8<-- "examples/push_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back.output" + ``` + +??? example "Example: (2) add element to object" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value + was silently converted to a JSON object. + + ```cpp + --8<-- "examples/push_back__object_t__value.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__object_t__value.output" + ``` + +??? example "Example: (3) add to object from initializer list" + + The example shows how initializer lists are treated as objects when possible. + + ```cpp + --8<-- "examples/push_back__initializer_list.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__initializer_list.output" + ``` + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +2. Since version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/rbegin.md b/json-develop/docs/mkdocs/docs/api/basic_json/rbegin.md new file mode 100644 index 0000000..126c471 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/rbegin.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::rbegin + +```cpp +reverse_iterator rbegin() noexcept; +const_reverse_iterator rbegin() const noexcept; +``` + +Returns an iterator to the reverse-beginning; that is, the last element. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `rbegin()`. + + ```cpp + --8<-- "examples/rbegin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/rbegin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/rend.md b/json-develop/docs/mkdocs/docs/api/basic_json/rend.md new file mode 100644 index 0000000..96da7a5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/rend.md @@ -0,0 +1,43 @@ +# nlohmann::basic_json::rend + +```cpp +reverse_iterator rend() noexcept; +const_reverse_iterator rend() const noexcept; +``` + +Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, +attempting to access it results in undefined behavior. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the element following the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `eend()`. + + ```cpp + --8<-- "examples/rend.cpp" + ``` + + Output: + + ```json + --8<-- "examples/rend.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/sax_parse.md b/json-develop/docs/mkdocs/docs/api/basic_json/sax_parse.md new file mode 100644 index 0000000..e2ac1b4 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/sax_parse.md @@ -0,0 +1,115 @@ +# nlohmann::basic_json::sax_parse + +```cpp +// (1) +template +static bool sax_parse(InputType&& i, + SAX* sax, + input_format_t format = input_format_t::json, + const bool strict = true, + const bool ignore_comments = false); + +// (2) +template +static bool sax_parse(IteratorType first, IteratorType last, + SAX* sax, + input_format_t format = input_format_t::json, + const bool strict = true, + const bool ignore_comments = false); +``` + +Read from input and generate SAX events + +1. Read from a compatible input. +2. Read from a pair of character iterators + + The value_type of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted + respectively as UTF-8, UTF-16 and UTF-32. + +The SAX event lister must follow the interface of [`json_sax`](../json_sax/index.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of + iterators. + +`IteratorType` +: Description + +`SAX` +: Description + +## Parameters + +`i` (in) +: Input to parse from. + +`sax` (in) +: SAX event listener + +`format` (in) +: the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, `input_format_t::json` by default), see + [`input_format_t`](input_format_t.md) for more information + +`strict` (in) +: whether the input has to be consumed completely (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to start of character range + +`last` (in) +: iterator to end of character range + +## Return value + +return value of the last processed SAX event + +## Exception safety + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the SAX +consumer `sax` has a super-linear complexity. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +## Examples + +??? example + + The example below demonstrates the `sax_parse()` function reading from string and processing the events with a + user-defined SAX event consumer. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. +- Ignoring comments via `ignore_comments` added in version 3.9.0. + +!!! warning "Deprecation" + + Overload (2) replaces calls to `sax_parse` with a pair of iterators as their first parameter which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp sax_parse({ptr, ptr+len});` with `#!cpp sax_parse(ptr, ptr+len);`. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/size.md b/json-develop/docs/mkdocs/docs/api/basic_json/size.md new file mode 100644 index 0000000..4ff582d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/size.md @@ -0,0 +1,57 @@ +# nlohmann::basic_json::size + +```cpp +size_type size() const noexcept; +``` + +Returns the number of elements in a JSON value. + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +|------------|-------------------------------------| +| null | `0` | +| boolean | `1` | +| string | `1` | +| number | `1` | +| binary | `1` | +| object | result of function object_t::size() | +| array | result of function array_t::size() | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the +[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `size()` functions have +constant complexity. + +## Notes + +This function does not return the length of a string stored as JSON value -- it returns the number of elements in the +JSON value which is `1` in the case of a string. + +## Examples + +??? example + + The following code calls `size()` on the different value types. + + ```cpp + --8<-- "examples/size.cpp" + ``` + + Output: + + ```json + --8<-- "examples/size.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Extended to return `1` for binary types in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/std_hash.md b/json-develop/docs/mkdocs/docs/api/basic_json/std_hash.md new file mode 100644 index 0000000..b9de74f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/std_hash.md @@ -0,0 +1,34 @@ +# std::hash + +```cpp +namespace std { + struct hash; +} +``` + +Return a hash value for a JSON object. The hash function tries to rely on `std::hash` where possible. Furthermore, the +type of the JSON value is taken into account to have different hash values for `#!json null`, `#!cpp 0`, `#!cpp 0U`, and +`#!cpp false`, etc. + +## Examples + +??? example + + The example shows how to calculate hash values for different JSON values. + + ```cpp + --8<-- "examples/std_hash.cpp" + ``` + + Output: + + ```json + --8<-- "examples/std_hash.output" + ``` + + Note the output is platform-dependent. + +## Version history + +- Added in version 1.0.0. +- Extended for arbitrary basic_json types in version 3.10.5. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/std_swap.md b/json-develop/docs/mkdocs/docs/api/basic_json/std_swap.md new file mode 100644 index 0000000..d30f3bc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/std_swap.md @@ -0,0 +1,51 @@ +# std::swap + +```cpp +namespace std { + void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2); +} +``` + +Exchanges the values of two JSON objects. + +## Parameters + +`j1` (in, out) +: value to be replaced by `j2` + +`j2` (in, out) +: value to be replaced by `j1` + +## Possible implementation + +```cpp +void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2) +{ + j1.swap(j2); +} +``` + +## Examples + +??? example + + The following code shows how two values are swapped with `std::swap`. + + ```cpp + --8<-- "examples/std_swap.cpp" + ``` + + Output: + + ```json + --8<-- "examples/std_swap.output" + ``` + +## See also + +- [swap](swap.md) + +## Version history + +- Added in version 1.0.0. +- Extended for arbitrary basic_json types in version 3.10.5. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/string_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/string_t.md new file mode 100644 index 0000000..3ab4412 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/string_t.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::string_t + +```cpp +using string_t = StringType; +``` + +The type used to store JSON strings. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: +> A string is a sequence of zero or more Unicode characters. + +To store objects in C++, a type is defined by the template parameter described below. Unicode values are split by the +JSON class into byte-sized characters during deserialization. + +## Template parameters + +`StringType` +: the container to store strings (e.g., `std::string`). Note this container is used for keys/names in objects, see + [object_t](object_t.md). + +## Notes + +#### Default type + +With the default values for `StringType` (`std::string`), the default value for `string_t` is `#!cpp std::string`. + +#### Encoding + +Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return +the number of bytes in the string rather than the number of characters or glyphs. + +#### String comparison + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: +> Software implementations are typically required to test names of object members for equality. Implementations that +> transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, +> code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or +> inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may +> incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. + +This implementation is interoperable as it does compare strings code unit by code unit. + +#### Storage + +String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type +`string_t*` must be dereferenced. + +## Examples + +??? example + + The following code shows that `string_t` is by default, a typedef to `#!cpp std::string`. + + ```cpp + --8<-- "examples/string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/string_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/swap.md b/json-develop/docs/mkdocs/docs/api/basic_json/swap.md new file mode 100644 index 0000000..a5730ff --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/swap.md @@ -0,0 +1,157 @@ +# nlohmann::basic_json::swap + +```cpp +// (1) +void swap(reference other) noexcept; + +// (2) +void swap(reference left, reference right) noexcept; + +// (3) +void swap(array_t& other); + +// (4) +void swap(object_t& other); + +// (5) +void swap(string_t& other); + +// (6) +void swap(binary_t& other); + +// (7) +void swap(typename binary_t::container_type& other); +``` + +1. Exchanges the contents of the JSON value with those of `other`. Does not invoke any move, copy, or swap operations on + individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. +2. Exchanges the contents of the JSON value from `left` with those of `right`. Does not invoke any move, copy, or swap + operations on individual elements. All iterators and references remain valid. The past-the-end iterator is + invalidated. Implemented as a friend function callable via ADL. +3. Exchanges the contents of a JSON array with those of `other`. Does not invoke any move, copy, or swap operations on + individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. +4. Exchanges the contents of a JSON object with those of `other`. Does not invoke any move, copy, or swap operations on + individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. +5. Exchanges the contents of a JSON string with those of `other`. Does not invoke any move, copy, or swap operations on + individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. +6. Exchanges the contents of a binary value with those of `other`. Does not invoke any move, copy, or swap operations on + individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. +7. Exchanges the contents of a binary value with those of `other`. Does not invoke any move, copy, or swap operations on + individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Unlike + version (6), no binary subtype is involved. + +## Parameters + +`other` (in, out) +: value to exchange the contents with + +`left` (in, out) +: value to exchange the contents with + +`right` (in, out) +: value to exchange the contents with + +## Exceptions + +1. No-throw guarantee: this function never throws exceptions. +2. No-throw guarantee: this function never throws exceptions. +3. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + arrays; example: `"cannot use swap() with boolean"` +4. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + objects; example: `"cannot use swap() with boolean"` +5. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + strings; example: `"cannot use swap() with boolean"` +6. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + binaries; example: `"cannot use swap() with boolean"` +7. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + binaries; example: `"cannot use swap() with boolean"` + +## Complexity + +Constant. + +## Examples + +??? example "Example: Swap JSON value (1, 2)" + + The example below shows how JSON values can be swapped with `swap()`. + + ```cpp + --8<-- "examples/swap__reference.cpp" + ``` + + Output: + + ```json + --8<-- "examples/swap__reference.output" + ``` + +??? example "Example: Swap array (3)" + + The example below shows how arrays can be swapped with `swap()`. + + ```cpp + --8<-- "examples/swap__array_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/swap__array_t.output" + ``` + +??? example "Example: Swap object (4)" + + The example below shows how objects can be swapped with `swap()`. + + ```cpp + --8<-- "examples/swap__object_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/swap__object_t.output" + ``` + +??? example "Example: Swap string (5)" + + The example below shows how strings can be swapped with `swap()`. + + ```cpp + --8<-- "examples/swap__string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/swap__string_t.output" + ``` + +??? example "Example: Swap string (6)" + + The example below shows how binary values can be swapped with `swap()`. + + ```cpp + --8<-- "examples/swap__binary_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/swap__binary_t.output" + ``` + +## See also + +- [std::swap](std_swap.md) + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +3. Since version 1.0.0. +4. Since version 1.0.0. +5. Since version 1.0.0. +6. Since version 3.8.0. +7. Since version 3.8.0. \ No newline at end of file diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/to_bjdata.md b/json-develop/docs/mkdocs/docs/api/basic_json/to_bjdata.md new file mode 100644 index 0000000..48598a5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/to_bjdata.md @@ -0,0 +1,70 @@ +# nlohmann::basic_json::to_bjdata + +```cpp +// (1) +static std::vector to_bjdata(const basic_json& j, + const bool use_size = false, + const bool use_type = false); + +// (2) +static void to_bjdata(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +static void to_bjdata(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +``` + +Serializes a given JSON value `j` to a byte vector using the BJData (Binary JData) serialization format. BJData aims to +be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the BJData serialization. +2. Writes the BJData serialization to an output adapter. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/bjdata.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +`use_size` (in) +: whether to add size annotations to container types; optional, `#!cpp false` by default. + +`use_type` (in) +: whether to add type annotations to container types (must be combined with `#!cpp use_size = true`); optional, +`#!cpp false` by default. + +## Return value + +1. BJData serialization as byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in BJData format. + + ```cpp + --8<-- "examples/to_bjdata.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_bjdata.output" + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/to_bson.md b/json-develop/docs/mkdocs/docs/api/basic_json/to_bson.md new file mode 100644 index 0000000..5c4324a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/to_bson.md @@ -0,0 +1,59 @@ +# nlohmann::basic_json::to_bson + +```cpp +// (1) +static std::vector to_bson(const basic_json& j); + +// (2) +static void to_bson(const basic_json& j, detail::output_adapter o); +static void to_bson(const basic_json& j, detail::output_adapter o); +``` + +BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are stored as a single entity (a +so-called document). + +1. Returns a byte vector containing the BSON serialization. +2. Writes the BSON serialization to an output adapter. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/bson.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +## Return value + +1. BSON serialization as byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in BSON format. + + ```cpp + --8<-- "examples/to_bson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_bson.output" + ``` + +## Version history + +- Added in version 3.4.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/to_cbor.md b/json-develop/docs/mkdocs/docs/api/basic_json/to_cbor.md new file mode 100644 index 0000000..0f944c4 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/to_cbor.md @@ -0,0 +1,61 @@ +# nlohmann::basic_json::to_cbor + +```cpp +// (1) +static std::vector to_cbor(const basic_json& j); + +// (2) +static void to_cbor(const basic_json& j, detail::output_adapter o); +static void to_cbor(const basic_json& j, detail::output_adapter o); +``` + +Serializes a given JSON value `j` to a byte vector using the CBOR (Concise Binary Object Representation) serialization +format. CBOR is a binary serialization format which aims to be more compact than JSON itself, yet more efficient to +parse. + +1. Returns a byte vector containing the CBOR serialization. +2. Writes the CBOR serialization to an output adapter. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/cbor.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +## Return value + +1. CBOR serialization as byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in CBOR format. + + ```cpp + --8<-- "examples/to_cbor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_cbor.output" + ``` + +## Version history + +- Added in version 2.0.9. +- Compact representation of floating-point numbers added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/to_msgpack.md b/json-develop/docs/mkdocs/docs/api/basic_json/to_msgpack.md new file mode 100644 index 0000000..7d40981 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/to_msgpack.md @@ -0,0 +1,59 @@ +# nlohmann::basic_json::to_msgpack + +```cpp +// (1) +static std::vector to_msgpack(const basic_json& j); + +// (2) +static void to_msgpack(const basic_json& j, detail::output_adapter o); +static void to_msgpack(const basic_json& j, detail::output_adapter o); +``` + +Serializes a given JSON value `j` to a byte vector using the MessagePack serialization format. MessagePack is a binary +serialization format which aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the MessagePack serialization. +2. Writes the MessagePack serialization to an output adapter. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/messagepack.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +## Return value + +1. MessagePack serialization as byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in MessagePack format. + + ```cpp + --8<-- "examples/to_msgpack.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_msgpack.output" + ``` + +## Version history + +- Added in version 2.0.9. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/to_string.md b/json-develop/docs/mkdocs/docs/api/basic_json/to_string.md new file mode 100644 index 0000000..2b907e2 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/to_string.md @@ -0,0 +1,65 @@ +# to_string(basic_json) + +```cpp +template +std::string to_string(const BasicJsonType& j); +``` + +This function implements a user-defined to_string for JSON objects. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](index.md) + +## Return value + +string containing the serialization of the JSON value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value +is not UTF-8 encoded + +## Complexity + +Linear. + +## Possible implementation + +```cpp +template +std::string to_string(const BasicJsonType& j) +{ + return j.dump(); +} +``` + +## Examples + +??? example + + The following code shows how the library's `to_string()` function integrates with others, allowing + argument-dependent lookup. + + ```cpp + --8<-- "examples/to_string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_string.output" + ``` + +## See also + +- [dump](dump.md) + +## Version history + +Added in version 3.7.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/to_ubjson.md b/json-develop/docs/mkdocs/docs/api/basic_json/to_ubjson.md new file mode 100644 index 0000000..e3cd5d6 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/to_ubjson.md @@ -0,0 +1,70 @@ +# nlohmann::basic_json::to_ubjson + +```cpp +// (1) +static std::vector to_ubjson(const basic_json& j, + const bool use_size = false, + const bool use_type = false); + +// (2) +static void to_ubjson(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +static void to_ubjson(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +``` + +Serializes a given JSON value `j` to a byte vector using the UBJSON (Universal Binary JSON) serialization format. UBJSON +aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the UBJSON serialization. +2. Writes the UBJSON serialization to an output adapter. + +The exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/ubjson.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +`use_size` (in) +: whether to add size annotations to container types; optional, `#!cpp false` by default. + +`use_type` (in) +: whether to add type annotations to container types (must be combined with `#!cpp use_size = true`); optional, + `#!cpp false` by default. + +## Return value + +1. UBJSON serialization as byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in UBJSON format. + + ```cpp + --8<-- "examples/to_ubjson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_ubjson.output" + ``` + +## Version history + +- Added in version 3.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/type.md b/json-develop/docs/mkdocs/docs/api/basic_json/type.md new file mode 100644 index 0000000..deedd6b --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/type.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::type + +```cpp +constexpr value_t type() const noexcept; +``` + +Return the type of the JSON value as a value from the [`value_t`](value_t.md) enumeration. + +## Return value + +the type of the JSON value + +| Value type | return value | +|---------------------------|----------------------------| +| `#!json null` | `value_t::null` | +| boolean | `value_t::boolean` | +| string | `value_t::string` | +| number (integer) | `value_t::number_integer` | +| number (unsigned integer) | `value_t::number_unsigned` | +| number (floating-point) | `value_t::number_float` | +| object | `value_t::object` | +| array | `value_t::array` | +| binary | `value_t::binary` | +| discarded | `value_t::discarded` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `type()` for all JSON types. + + ```cpp + --8<-- "examples/type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/type_error.md b/json-develop/docs/mkdocs/docs/api/basic_json/type_error.md new file mode 100644 index 0000000..cda54c0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/type_error.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::type_error + +```cpp +class type_error : public exception; +``` + +This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type +does not match the expected semantics. + +Exceptions have ids 3xx (see [list of type errors](../../home/exceptions.md#type-errors)). + +```plantuml +std::exception <|-- basic_json::exception +basic_json::exception <|-- basic_json::parse_error +basic_json::exception <|-- basic_json::invalid_iterator +basic_json::exception <|-- basic_json::type_error +basic_json::exception <|-- basic_json::out_of_range +basic_json::exception <|-- basic_json::other_error + +interface std::exception {} + +class basic_json::exception { + + const int id + + const char* what() const +} + +class basic_json::parse_error { + + const std::size_t byte +} + +class basic_json::type_error #FFFF00 {} +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `type_error` exception can be caught. + + ```cpp + --8<-- "examples/type_error.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type_error.output" + ``` + +## See also + +- [List of type errors](../../home/exceptions.md#type-errors) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/type_name.md b/json-develop/docs/mkdocs/docs/api/basic_json/type_name.md new file mode 100644 index 0000000..389c2b1 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/type_name.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::type_name + +```cpp +const char* type_name() const noexcept; +``` + +Returns the type name as string to be used in error messages -- usually to indicate that a function was called on a +wrong JSON type. + +## Return value + +a string representation of the type ([`value_t`](value_t.md)): + +| Value type | return value | +|----------------------------------------------------|---------------| +| `#!json null` | `"null"` | +| boolean | `"boolean"` | +| string | `"string"` | +| number (integer, unsigned integer, floating-point) | `"number"` | +| object | `"object"` | +| array | `"array"` | +| binary | `"binary"` | +| discarded | `"discarded"` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `type_name()` for all JSON types. + + ```cpp + --8<-- "examples/type_name.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type_name.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Part of the public API version since 2.1.0. +- Changed return value to `const char*` and added `noexcept` in version 3.0.0. +- Added support for binary type in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/unflatten.md b/json-develop/docs/mkdocs/docs/api/basic_json/unflatten.md new file mode 100644 index 0000000..d977803 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/unflatten.md @@ -0,0 +1,61 @@ +# nlohmann::basic_json::unflatten + +```cpp +basic_json unflatten() const; +``` + +The function restores the arbitrary nesting of a JSON value that has been flattened before using the +[`flatten()`](flatten.md) function. The JSON value must meet certain constraints: + +1. The value must be an object. +2. The keys must be JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901)) +3. The mapped values must be primitive JSON types. + +## Return value + +the original JSON from a flattened version + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +The function can throw the following exceptions: + +- Throws [`type_error.314`](../../home/exceptions.md#jsonexceptiontype_error314) if value is not an object +- Throws [`type_error.315`](../../home/exceptions.md#jsonexceptiontype_error315) if object values are not primitive + +## Complexity + +Linear in the size the JSON value. + +## Notes + +Empty objects and arrays are flattened by [`flatten()`](flatten.md) to `#!json null` values and can not unflattened to +their original type. Apart from this example, for a JSON value `j`, the following is always true: +`#!cpp j == j.flatten().unflatten()`. + +## Examples + +??? example + + The following code shows how a flattened JSON object is unflattened into the original nested JSON object. + + ```cpp + --8<-- "examples/unflatten.cpp" + ``` + + Output: + + ```json + --8<-- "examples/unflatten.output" + ``` + +## See also + +- [flatten](flatten.md) the reverse function + +## Version history + +- Added in version 2.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/update.md b/json-develop/docs/mkdocs/docs/api/basic_json/update.md new file mode 100644 index 0000000..a594cf9 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/update.md @@ -0,0 +1,142 @@ +# nlohmann::basic_json::update + +```cpp +// (1) +void update(const_reference j, bool merge_objects = false); + +// (2) +void update(const_iterator first, const_iterator last, bool merge_objects = false); +``` + +1. Inserts all values from JSON object `j`. +2. Inserts all values from range `[first, last)` + +When `merge_objects` is `#!c false` (default), existing keys are overwritten. When `merge_objects` is `#!c true`, +recursively merges objects with common keys. + +The function is motivated by Python's [dict.update](https://docs.python.org/3.6/library/stdtypes.html#dict.update) +function. + +## Parameters + +`j` (in) +: JSON object to read values from + +`merge_objects` (in) +: when `#!c true`, existing keys are not overwritten, but contents of objects are merged recursively (default: + `#!c false`) + +`first` (in) +: begin of the range of elements to insert + +`last` (in) +: end of the range of elements to insert + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.312`](../../home/exceptions.md#jsonexceptiontype_error312) if called on JSON values other than + objects; example: `"cannot use update() with string"` +2. The function can throw the following exceptions: + - Throws [`type_error.312`](../../home/exceptions.md#jsonexceptiontype_error312) if called on JSON values other than + objects; example: `"cannot use update() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last` + do not belong to the same JSON value; example: `"iterators do not fit"` + +## Complexity + +1. O(N*log(size() + N)), where N is the number of elements to insert. +2. O(N*log(size() + N)), where N is the number of elements to insert. + +## Examples + +??? example + + The example shows how `update()` is used. + + ```cpp + --8<-- "examples/update.cpp" + ``` + + Output: + + ```json + --8<-- "examples/update.output" + ``` + +??? example + + The example shows how `update()` is used. + + ```cpp + --8<-- "examples/update__range.cpp" + ``` + + Output: + + ```json + --8<-- "examples/update__range.output" + ``` + +??? example + + One common use case for this function is the handling of user settings. Assume your application can be configured in + some aspects: + + ```json + { + "color": "red", + "active": true, + "name": {"de": "Maus", "en": "mouse"} + } + ``` + + The user may override the default settings selectively: + + ```json + { + "color": "blue", + "name": {"es": "ratón"}, + } + ``` + + Then `update` manages the merging of default settings and user settings: + + ```cpp + auto user_settings = json::parse("config.json"); + auto effective_settings = get_default_settings(); + effective_settings.update(user_settings); + ``` + + Now `effective_settings` contains the default settings, but those keys set by the user are overwritten: + + ```json + { + "color": "blue", + "active": true, + "name": {"es": "ratón"} + } + ``` + + Note existing keys were just overwritten. To merge objects, `merge_objects` setting should be set to `#!c true`: + + ```cpp + auto user_settings = json::parse("config.json"); + auto effective_settings = get_default_settings(); + effective_settings.update(user_settings, true); + ``` + + ```json + { + "color": "blue", + "active": true, + "name": {"de": "Maus", "en": "mouse", "es": "ratón"} + } + ``` + +## Version history + +- Added in version 3.0.0. +- Added `merge_objects` parameter in 3.10.4. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/value.md b/json-develop/docs/mkdocs/docs/api/basic_json/value.md new file mode 100644 index 0000000..edb5406 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/value.md @@ -0,0 +1,159 @@ +# nlohmann::basic_json::value + +```cpp +// (1) +template +ValueType value(const typename object_t::key_type& key, + ValueType&& default_value) const; + +// (2) +template +ValueType value(KeyType&& key, + ValueType&& default_value) const; + +// (3) +template +ValueType value(const json_pointer& ptr, + const ValueType& default_value) const; +``` + +1. Returns either a copy of an object's element at the specified key `key` or a given default value if no element with + key `key` exists. + + The function is basically equivalent to executing + ```cpp + try { + return at(key); + } catch(out_of_range) { + return default_value; + } + ``` + +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +3. Returns either a copy of an object's element at the specified JSON pointer `ptr` or a given default value if no value + at `ptr` exists. + + The function is basically equivalent to executing + ```cpp + try { + return at(ptr); + } catch(out_of_range) { + return default_value; + } + ``` + +!!! note "Differences to `at` and `operator[]`" + + - Unlike [`at`](at.md), this function does not throw if the given `key`/`ptr` was not found. + - Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by + `key`/`ptr` key. This function is furthermore also applicable to const objects. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). +`ValueType` +: type compatible to JSON values, for instance `#!cpp int` for JSON integer numbers, `#!cpp bool` for JSON booleans, + or `#!cpp std::vector` types for JSON arrays. Note the type of the expected value at `key`/`ptr` and the default + value `default_value` must be compatible. + +## Parameters + +`key` (in) +: key of the element to access + +`default_value` (in) +: the value to return if `key`/`ptr` found no value + +`ptr` (in) +: a JSON pointer to the element to access + +## Return value + +1. copy of the element at key `key` or `default_value` if `key` is not found +2. copy of the element at key `key` or `default_value` if `key` is not found +3. copy of the element at JSON Pointer `ptr` or `default_value` if no value for `ptr` is found + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no +changes to any JSON value. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `default_value` does not match + the type of the value at `key` + - Throws [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) if the JSON value is not an object; + in that case, using `value()` with a key makes no sense. +2. See 1. +3. The function can throw the following exceptions: + - Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `default_value` does not match + the type of the value at `ptr` + - Throws [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) if the JSON value is not an object; + in that case, using `value()` with a key makes no sense. + +## Complexity + +1. Logarithmic in the size of the container. +2. Logarithmic in the size of the container. +3. Logarithmic in the size of the container. + +## Examples + +??? example "Example: (1) access specified object element with default value" + + The example below shows how object elements can be queried with a default value. + + ```cpp + --8<-- "examples/value__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__object_t_key_type.output" + ``` + +??? example "Example: (2) access specified object element using string_view with default value" + + The example below shows how object elements can be queried with a default value. + + ```cpp + --8<-- "examples/value__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__keytype.c++17.output" + ``` + +??? example "Example: (3) access specified object element via JSON Pointer with default value" + + The example below shows how object elements can be queried with a default value. + + ```cpp + --8<-- "examples/value__json_ptr.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__json_ptr.output" + ``` + +## See also + +- see [`at`](at.md) for access by reference with range checking +- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference + +## Version history + +1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0. +2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2. +3. Added in version 2.0.2. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/value_t.md b/json-develop/docs/mkdocs/docs/api/basic_json/value_t.md new file mode 100644 index 0000000..1505e02 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/value_t.md @@ -0,0 +1,81 @@ +# nlohmann::basic_json::value_t + +```cpp +enum class value_t : std::uint8_t { + null, + object, + array, + string, + boolean, + number_integer, + number_unsigned, + number_float, + binary, + discarded +}; +``` + +This enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the +functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_array.md), [`is_string`](is_string.md), +[`is_boolean`](is_boolean.md), [`is_number`](is_number.md) (with [`is_number_integer`](is_number_integer.md), +[`is_number_unsigned`](is_number_unsigned.md), and [`is_number_float`](is_number_float.md)), +[`is_discarded`](is_discarded.md), [`is_binary`](is_binary.md), [`is_primitive`](is_primitive.md), and +[`is_structured`](is_structured.md) rely on it. + +## Notes + +!!! note "Ordering" + + The order of types is as follows: + + 1. `null` + 2. `boolean` + 3. `number_integer`, `number_unsigned`, `number_float` + 4. `object` + 5. `array` + 6. `string` + 7. `binary` + + `discarded` is unordered. + +!!! note "Types of numbers" + + There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish + between different types of numbers: + + - [`number_unsigned_t`](number_unsigned_t.md) for unsigned integers + - [`number_integer_t`](number_integer_t.md) for signed integers + - [`number_float_t`](number_float_t.md) for floating-point numbers or to approximate integers which do not fit + into the limits of their respective type + +!!! warning "Comparison operators" + + `operator<` and `operator<=>` (since C++20) are overloaded and compare according to the ordering described above. + Until C++20 all other relational and equality operators yield results according to the integer value of each + enumerator. Since C++20 some compilers consider the _rewritten candidates_ generated from `operator<=>` during + overload resolution, while others do not. For predictable and portable behavior use: + + - `operator<` or `operator<=>` when wanting to compare according to the order described above + - `operator==` or `operator!=` when wanting to compare according to each enumerators integer value + +## Examples + +??? example + + The following code how `type()` queries the `value_t` for all JSON types. + + ```cpp + --8<-- "examples/type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/basic_json/~basic_json.md b/json-develop/docs/mkdocs/docs/api/basic_json/~basic_json.md new file mode 100644 index 0000000..64e9440 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/basic_json/~basic_json.md @@ -0,0 +1,21 @@ +# nlohmann::basic_json::~basic_json + +```cpp +~basic_json() noexcept; +``` + +Destroys the JSON value and frees all allocated memory. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Linear. + + + +## Version history + +- Added in version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/byte_container_with_subtype.md b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/byte_container_with_subtype.md new file mode 100644 index 0000000..9913a9b --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/byte_container_with_subtype.md @@ -0,0 +1,46 @@ +# nlohmann::byte_container_with_subtype::byte_container_with_subtype + +```cpp +// (1) +byte_container_with_subtype(); + +// (2) +byte_container_with_subtype(const container_type& container); +byte_container_with_subtype(container_type&& container); + +// (3) +byte_container_with_subtype(const container_type& container, subtype_type subtype); +byte_container_with_subtype(container_type&& container, subtype_type subtype); +``` + +1. Create empty binary container without subtype. +2. Create binary container without subtype. +3. Create binary container with subtype. + +## Parameters + +`container` (in) +: binary container + +`subtype` (in) +: subtype + +## Examples + +??? example + + The example below demonstrates how byte containers can be created. + + ```cpp + --8<-- "examples/byte_container_with_subtype__byte_container_with_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__byte_container_with_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/clear_subtype.md b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/clear_subtype.md new file mode 100644 index 0000000..c62dead --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/clear_subtype.md @@ -0,0 +1,36 @@ +# nlohmann::byte_container_with_subtype::clear_subtype + +```cpp +void clear_subtype() noexcept; +``` + +Clears the binary subtype and flags the value as not having a subtype, which has implications for serialization; for +instance MessagePack will prefer the bin family over the ext family. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how `clear_subtype` can remove subtypes. + + ```cpp + --8<-- "examples/byte_container_with_subtype__clear_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__clear_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/has_subtype.md b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/has_subtype.md new file mode 100644 index 0000000..e06286e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/has_subtype.md @@ -0,0 +1,39 @@ +# nlohmann::byte_container_with_subtype::has_subtype + +```cpp +constexpr bool has_subtype() const noexcept; +``` + +Returns whether the value has a subtype. + +## Return value + +whether the value has a subtype + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how `has_subtype` can check whether a subtype was set. + + ```cpp + --8<-- "examples/byte_container_with_subtype__has_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__has_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/index.md b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/index.md new file mode 100644 index 0000000..277fffa --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/index.md @@ -0,0 +1,35 @@ +# nlohmann::byte_container_with_subtype + +```cpp +template +class byte_container_with_subtype : public BinaryType; +``` + +This type extends the template parameter `BinaryType` provided to [`basic_json`](../basic_json/index.md) with a subtype +used by BSON and MessagePack. This type exists so that the user does not have to specify a type themselves with a +specific naming scheme in order to override the binary type. + +## Template parameters + +`BinaryType` +: container to store bytes (`#!cpp std::vector` by default) + +## Member types + +- **container_type** - the type of the underlying container (`BinaryType`) +- **subtype_type** - the type of the subtype (`#!cpp std::uint64_t`) + +## Member functions + +- [(constructor)](byte_container_with_subtype.md) +- **operator==** - comparison: equal +- **operator!=** - comparison: not equal +- [**set_subtype**](subtype.md) - sets the binary subtype +- [**subtype**](subtype.md) - return the binary subtype +- [**has_subtype**](has_subtype.md) - return whether the value has a subtype +- [**clear_subtype**](clear_subtype.md) - clears the binary subtype + +## Version history + +- Added in version 3.8.0. +- Changed type of subtypes to `#!cpp std::uint64_t` in 3.10.0. diff --git a/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/set_subtype.md b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/set_subtype.md new file mode 100644 index 0000000..cf21732 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/set_subtype.md @@ -0,0 +1,41 @@ +# nlohmann::byte_container_with_subtype::set_subtype + +```cpp +void set_subtype(subtype_type subtype) noexcept; +``` + +Sets the binary subtype of the value, also flags a binary JSON value as having a subtype, which has implications for +serialization. + +## Parameters + +`subtype` (in) +: subtype to set + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how a subtype can be set with `set_subtype`. + + ```cpp + --8<-- "examples/byte_container_with_subtype__set_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__set_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/subtype.md b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/subtype.md new file mode 100644 index 0000000..389241a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/byte_container_with_subtype/subtype.md @@ -0,0 +1,42 @@ +# nlohmann::byte_container_with_subtype::subtype + +```cpp +constexpr subtype_type subtype() const noexcept; +``` + +Returns the numerical subtype of the value if it has a subtype. If it does not have a subtype, this function will return +`subtype_type(-1)` as a sentinel value. + +## Return value + +the numerical subtype of the binary value, or `subtype_type(-1)` if no subtype is set + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how the subtype can be retrieved with `subtype`. Note how `subtype_type(-1)` is + returned for container `c1`. + + ```cpp + --8<-- "examples/byte_container_with_subtype__subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__subtype.output" + ``` + +## Version history + +- Added in version 3.8.0 +- Fixed return value to properly return `subtype_type(-1)` as documented in version 3.10.0. diff --git a/json-develop/docs/mkdocs/docs/api/json.md b/json-develop/docs/mkdocs/docs/api/json.md new file mode 100644 index 0000000..36edcc2 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json.md @@ -0,0 +1,28 @@ +# nlohmann::json + +```cpp +using json = basic_json<>; +``` + +This type is the default specialization of the [basic_json](basic_json/index.md) class which uses the standard template +types. + +## Examples + +??? example + + The example below demonstrates how to use the type `nlohmann::json`. + + ```cpp + --8<-- "examples/README.cpp" + ``` + + Output: + + ```json + --8<-- "examples/README.output" + ``` + +## Version history + +Since version 1.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/back.md b/json-develop/docs/mkdocs/docs/api/json_pointer/back.md new file mode 100644 index 0000000..240bc6e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/back.md @@ -0,0 +1,40 @@ +# nlohmann::json_pointer::back + +```cpp +const string_t& back() const; +``` + +Return last reference token. + +## Return value + +Last reference token. + +## Exceptions + +Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the usage of `back`. + + ```cpp + --8<-- "examples/json_pointer__back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__back.output" + ``` + +## Version history + +- Added in version 3.6.0. +- Changed return type to `string_t` in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/empty.md b/json-develop/docs/mkdocs/docs/api/json_pointer/empty.md new file mode 100644 index 0000000..346364a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/empty.md @@ -0,0 +1,39 @@ +# nlohmann::json_pointer::empty + +```cpp +bool empty() const noexcept; +``` + +Return whether pointer points to the root document. + +## Return value + +`#!cpp true` iff the JSON pointer points to the root document. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the result of `empty` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__empty.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__empty.output" + ``` + +## Version history + +Added in version 3.6.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/index.md b/json-develop/docs/mkdocs/docs/api/json_pointer/index.md new file mode 100644 index 0000000..22e2464 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/index.md @@ -0,0 +1,52 @@ +# nlohmann::json_pointer + +```cpp +template +class json_pointer; +``` + +A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with +functions [`at`](../basic_json/at.md) and [`operator[]`](../basic_json/operator%5B%5D.md). Furthermore, JSON pointers +are the base for JSON patches. + +## Template parameters + +`RefStringType` +: the string type used for the reference tokens making up the JSON pointer + +!!! warning "Deprecation" + + For backwards compatibility `RefStringType` may also be a specialization of [`basic_json`](../basic_json/index.md) + in which case `string_t` will be deduced as [`basic_json::string_t`](../basic_json/string_t.md). This feature is + deprecated and may be removed in a future major version. + +## Member types + +- [**string_t**](string_t.md) - the string type used for the reference tokens + +## Member functions + +- [(constructor)](json_pointer.md) +- [**to_string**](to_string.md) - return a string representation of the JSON pointer +- [**operator string_t**](operator_string_t.md) - return a string representation of the JSON pointer +- [**operator==**](operator_eq.md) - compare: equal +- [**operator!=**](operator_ne.md) - compare: not equal +- [**operator/=**](operator_slasheq.md) - append to the end of the JSON pointer +- [**operator/**](operator_slash.md) - create JSON Pointer by appending +- [**parent_pointer**](parent_pointer.md) - returns the parent of this JSON pointer +- [**pop_back**](pop_back.md) - remove last reference token +- [**back**](back.md) - return last reference token +- [**push_back**](push_back.md) - append an unescaped token at the end of the pointer +- [**empty**](empty.md) - return whether pointer points to the root document + +## Literals + +- [**operator""_json_pointer**](../operator_literal_json_pointer.md) - user-defined string literal for JSON pointers +## See also + +- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901) + +## Version history + +- Added in version 2.0.0. +- Changed template parameter from `basic_json` to string type in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/json_pointer.md b/json-develop/docs/mkdocs/docs/api/json_pointer/json_pointer.md new file mode 100644 index 0000000..5e7057f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/json_pointer.md @@ -0,0 +1,41 @@ +# nlohmann::json_pointer::json_pointer + +```cpp +explicit json_pointer(const string_t& s = ""); +``` + +Create a JSON pointer according to the syntax described in +[Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). + +## Parameters + +`s` (in) +: string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value + +## Exceptions + +- Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is + nonempty and does not begin with a slash (`/`); see example below. +- Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON + pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Examples + +??? example + + The example shows the construction several valid JSON pointers as well as the exceptional behavior. + + ```cpp + --8<-- "examples/json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer.output" + ``` + +## Version history + +- Added in version 2.0.0. +- Changed type of `s` to `string_t` in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/operator_eq.md b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_eq.md new file mode 100644 index 0000000..807ae1d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_eq.md @@ -0,0 +1,113 @@ +# nlohmann::json_pointer::operator== + +```cpp +// until C++20 +template +bool operator==( + const json_pointer& lhs, + const json_pointer& rhs) noexcept; // (1) + +template +bool operator==( + const json_pointer& lhs, + const StringType& rhs); // (2) + +template +bool operator==( + const StringType& lhs, + const json_pointer& rhs); // (2) + +// since C++20 +class json_pointer { + template + bool operator==( + const json_pointer& rhs) const noexcept; // (1) + + bool operator==(const string_t& rhs) const; // (2) +}; +``` + +1. Compares two JSON pointers for equality by comparing their reference tokens. + +2. Compares a JSON pointer and a string or a string and a JSON pointer for equality by converting the string to a JSON + pointer and comparing the JSON pointers according to 1. + +## Template parameters + +`RefStringTypeLhs`, `RefStringTypeRhs` +: the string type of the left-hand side or right-hand side JSON pointer, respectively + +`StringType` +: the string type derived from the `json_pointer` operand ([`json_pointer::string_t`](string_t.md)) + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are equal + +## Exception safety + +1. No-throw guarantee: this function never throws exceptions. +2. Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. (none) +2. The function can throw the following exceptions: + - Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is + nonempty and does not begin with a slash (`/`); see example below. + - Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON + pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Complexity + +Constant if `lhs` and `rhs` differ in the number of reference tokens, otherwise linear in the number of reference +tokens. + +## Notes + +!!! warning "Deprecation" + + Overload 2 is deprecated and will be removed in a future major version release. + +## Examples + +??? example "Example: (1) Comparing JSON pointers" + + The example demonstrates comparing JSON pointers. + + ```cpp + --8<-- "examples/json_pointer__operator__equal.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__equal.output" + ``` + +??? example "Example: (2) Comparing JSON pointers and strings" + + The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception. + + ```cpp + --8<-- "examples/json_pointer__operator__equal_stringtype.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__equal_stringtype.output" + ``` + +## Version history + +1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2. +2. Added for backward compatibility and deprecated in version 3.11.2. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/operator_ne.md b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_ne.md new file mode 100644 index 0000000..1f3e324 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_ne.md @@ -0,0 +1,109 @@ +# nlohmann::json_pointer::operator!= + +```cpp +// until C++20 +template +bool operator!=( + const json_pointer& lhs, + const json_pointer& rhs) noexcept; // (1) + +template +bool operator!=( + const json_pointer& lhs, + const StringType& rhs); // (2) + +template +bool operator!=( + const StringType& lhs, + const json_pointer& rhs); // (2) +``` + +1. Compares two JSON pointers for inequality by comparing their reference tokens. + +2. Compares a JSON pointer and a string or a string and a JSON pointer for inequality by converting the string to a + JSON pointer and comparing the JSON pointers according to 1. + +## Template parameters + +`RefStringTypeLhs`, `RefStringTypeRhs` +: the string type of the left-hand side or right-hand side JSON pointer, respectively + +`StringType` +: the string type derived from the `json_pointer` operand ([`json_pointer::string_t`](string_t.md)) + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are not equal + +## Exception safety + +1. No-throw guarantee: this function never throws exceptions. +2. Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. (none) +2. The function can throw the following exceptions: + - Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is + nonempty and does not begin with a slash (`/`); see example below. + - Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON + pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Complexity + +Constant if `lhs` and `rhs` differ in the number of reference tokens, otherwise linear in the number of reference +tokens. + +## Notes + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator==`](operator_eq.md). + +!!! warning "Deprecation" + + Overload 2 is deprecated and will be removed in a future major version release. + +## Examples + +??? example "Example: (1) Comparing JSON pointers" + + The example demonstrates comparing JSON pointers. + + ```cpp + --8<-- "examples/json_pointer__operator__notequal.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__notequal.output" + ``` + +??? example "Example: (2) Comparing JSON pointers and strings" + + The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception. + + ```cpp + --8<-- "examples/json_pointer__operator__notequal_stringtype.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__notequal_stringtype.output" + ``` + +## Version history + +1. Added in version 2.1.0. +2. Added for backward compatibility and deprecated in version 3.11.2. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/operator_slash.md b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_slash.md new file mode 100644 index 0000000..ed77b50 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_slash.md @@ -0,0 +1,64 @@ +# nlohmann::json_pointer::operator/ + +```cpp +// (1) +json_pointer operator/(const json_pointer& lhs, const json_pointer& rhs); + +// (2) +json_pointer operator/(const json_pointer& lhs, string_t token); + +// (3) +json_pointer operator/(const json_pointer& lhs, std::size_t array_idx); +``` + +1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer +2. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer +3. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer + +## Parameters + +`lhs` (in) +: JSON pointer + +`rhs` (in) +: JSON pointer to append + +`token` (in) +: reference token to append + +`array_idx` (in) +: array index to append + +## Return value + +1. a new JSON pointer with `rhs` appended to `lhs` +2. a new JSON pointer with unescaped `token` appended to `lhs` +3. a new JSON pointer with `array_idx` appended to `lhs` + +## Complexity + +1. Linear in the length of `lhs` and `rhs`. +2. Linear in the length of `lhs`. +3. Linear in the length of `lhs`. + +## Examples + +??? example + + The example shows the usage of `operator/`. + + ```cpp + --8<-- "examples/json_pointer__operator_add_binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__operator_add_binary.output" + ``` + +## Version history + +1. Added in version 3.6.0. +2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. +3. Added in version 3.6.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md new file mode 100644 index 0000000..3518557 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md @@ -0,0 +1,61 @@ +# nlohmann::json_pointer::operator/= + +```cpp +// (1) +json_pointer& operator/=(const json_pointer& ptr); + +// (2) +json_pointer& operator/=(string_t token); + +// (3) +json_pointer& operator/=(std::size_t array_idx) +``` + +1. append another JSON pointer at the end of this JSON pointer +2. append an unescaped reference token at the end of this JSON pointer +3. append an array index at the end of this JSON pointer + +## Parameters + +`ptr` (in) +: JSON pointer to append + +`token` (in) +: reference token to append + +`array_idx` (in) +: array index to append + +## Return value + +1. JSON pointer with `ptr` appended +2. JSON pointer with `token` appended without escaping `token` +3. JSON pointer with `array_idx` appended + +## Complexity + +1. Linear in the length of `ptr`. +2. Amortized constant. +3. Amortized constant. + +## Examples + +??? example + + The example shows the usage of `operator/=`. + + ```cpp + --8<-- "examples/json_pointer__operator_add.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__operator_add.output" + ``` + +## Version history + +1. Added in version 3.6.0. +2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. +3. Added in version 3.6.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/operator_string_t.md b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_string_t.md new file mode 100644 index 0000000..74105a4 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/operator_string_t.md @@ -0,0 +1,48 @@ +# nlohmann::json_pointer::operator string_t + +```cpp +operator string_t() const +``` + +Return a string representation of the JSON pointer. + +## Return value + +A string representation of the JSON pointer + +## Possible implementation + +```cpp +operator string_t() const +{ + return to_string(); +} +``` + +## Notes + +!!! warning "Deprecation" + + This function is deprecated in favor of [`to_string`](to_string.md) and will be removed in a future major version + release. + +## Examples + +??? example + + The example shows how JSON Pointers can be implicitly converted to strings. + + ```cpp + --8<-- "examples/json_pointer__operator_string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__operator_string_t.output" + ``` + +## Version history + +- Since version 2.0.0. +- Changed type to `string_t` and deprecated in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/parent_pointer.md b/json-develop/docs/mkdocs/docs/api/json_pointer/parent_pointer.md new file mode 100644 index 0000000..1398730 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/parent_pointer.md @@ -0,0 +1,35 @@ +# nlohmann::json_pointer::parent_pointer + +```cpp +json_pointer parent_pointer() const; +``` + +Returns the parent of this JSON pointer. + +## Return value + +Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned. + +## Complexity + +Linear in the length of the JSON pointer. + +## Examples + +??? example + + The example shows the result of `parent_pointer` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__parent_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__parent_pointer.output" + ``` + +## Version history + +Added in version 3.6.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/pop_back.md b/json-develop/docs/mkdocs/docs/api/json_pointer/pop_back.md new file mode 100644 index 0000000..3c79f36 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/pop_back.md @@ -0,0 +1,35 @@ +# nlohmann::json_pointer::pop_back + +```cpp +void pop_back(); +``` + +Remove last reference token. + +## Exceptions + +Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the usage of `pop_back`. + + ```cpp + --8<-- "examples/json_pointer__pop_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__pop_back.output" + ``` + +## Version history + +Added in version 3.6.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/push_back.md b/json-develop/docs/mkdocs/docs/api/json_pointer/push_back.md new file mode 100644 index 0000000..c1c19cb --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/push_back.md @@ -0,0 +1,39 @@ +# nlohmann::json_pointer::push_back + +```cpp +void push_back(const string_t& token); + +void push_back(string_t&& token); +``` + +Append an unescaped token at the end of the reference pointer. + +## Parameters + +`token` (in) +: token to add + +## Complexity + +Amortized constant. + +## Examples + +??? example + + The example shows the result of `push_back` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__push_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__push_back.output" + ``` + +## Version history + +- Added in version 3.6.0. +- Changed type of `token` to `string_t` in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/string_t.md b/json-develop/docs/mkdocs/docs/api/json_pointer/string_t.md new file mode 100644 index 0000000..c8527bc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/string_t.md @@ -0,0 +1,28 @@ +# nlohmann::json_pointer::string_t +```cpp +using string_t = RefStringType; +``` + +The string type used for the reference tokens making up the JSON pointer. + +See [`basic_json::string_t`](../basic_json/string_t.md) for more information. + +## Examples + +??? example + + The example shows the type `string_t` and its relation to `basic_json::string_t`. + + ```cpp + --8<-- "examples/json_pointer__string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__string_t.output" + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_pointer/to_string.md b/json-develop/docs/mkdocs/docs/api/json_pointer/to_string.md new file mode 100644 index 0000000..fae3abe --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_pointer/to_string.md @@ -0,0 +1,40 @@ +# nlohmann::json_pointer::to_string + +```cpp +string_t to_string() const; +``` + +Return a string representation of the JSON pointer. + +## Return value + +A string representation of the JSON pointer + +## Notes + +For each JSON pointer `ptr`, it holds: + +```cpp +ptr == json_pointer(ptr.to_string()); +``` + +## Examples + +??? example + + The example shows the result of `to_string`. + + ```cpp + --8<-- "examples/json_pointer__to_string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__to_string.output" + ``` + +## Version history + +- Since version 2.0.0. +- Changed return type to `string_t` in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/binary.md b/json-develop/docs/mkdocs/docs/api/json_sax/binary.md new file mode 100644 index 0000000..fc0980e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/binary.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::binary + +```cpp +virtual bool binary(binary_t& val) = 0; +``` + +A binary value was read. + +## Parameters + +`val` (in) +: binary value + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed binary value. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse__binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse__binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/boolean.md b/json-develop/docs/mkdocs/docs/api/json_sax/boolean.md new file mode 100644 index 0000000..fdf2945 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/boolean.md @@ -0,0 +1,36 @@ +# nlohmann::json_sax::boolean + +```cpp +virtual bool boolean(bool val) = 0; +``` + +A boolean value was read. + +## Parameters + +`val` (in) +: boolean value + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/end_array.md b/json-develop/docs/mkdocs/docs/api/json_sax/end_array.md new file mode 100644 index 0000000..9c12e40 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/end_array.md @@ -0,0 +1,31 @@ +# nlohmann::json_sax::end_array + +```cpp +virtual bool end_array() = 0; +``` + +The end of an array was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/end_object.md b/json-develop/docs/mkdocs/docs/api/json_sax/end_object.md new file mode 100644 index 0000000..601c94a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/end_object.md @@ -0,0 +1,31 @@ +# nlohmann::json_sax::end_object + +```cpp +virtual bool end_object() = 0; +``` + +The end of an object was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/index.md b/json-develop/docs/mkdocs/docs/api/json_sax/index.md new file mode 100644 index 0000000..f63e85c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/index.md @@ -0,0 +1,44 @@ +# nlohmann::json_sax + +```cpp +template +struct json_sax; +``` + +This class describes the SAX interface used by [sax_parse](../basic_json/sax_parse.md). Each function is called in +different situations while the input is parsed. The boolean return value informs the parser whether to continue +processing the input. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](../basic_json/index.md) + +## Member types + +- [**number_integer_t**](../basic_json/number_integer_t.md) - `BasicJsonType`'s type for numbers (integer) +- [**number_unsigned_t**](../basic_json/number_unsigned_t.md) - `BasicJsonType`'s type for numbers (unsigned) +- [**number_float_t**](../basic_json/number_float_t.md) - `BasicJsonType`'s type for numbers (floating-point) +- [**string_t**](../basic_json/string_t.md) - `BasicJsonType`'s type for strings +- [**binary_t**](../basic_json/binary_t.md) - `BasicJsonType`'s type for binary arrays + +## Member functions + +- [**binary**](binary.md) (_virtual_) - a binary value was read +- [**boolean**](boolean.md) (_virtual_) - a boolean value was read +- [**end_array**](end_array.md) (_virtual_) - the end of an array was read +- [**end_object**](end_object.md) (_virtual_) - the end of an object was read +- [**key**](key.md) (_virtual_) - an object key was read +- [**null**](null.md) (_virtual_) - a null value was read +- [**number_float**](number_float.md) (_virtual_) - a floating-point number was read +- [**number_integer**](number_integer.md) (_virtual_) - an integer number was read +- [**number_unsigned**](number_unsigned.md) (_virtual_) - an unsigned integer number was read +- [**parse_error**](parse_error.md) (_virtual_) - a parse error occurred +- [**start_array**](start_array.md) (_virtual_) - the beginning of an array was read +- [**start_object**](start_object.md) (_virtual_) - the beginning of an object was read +- [**string**](string.md) (_virtual_) - a string value was read + +## Version history + +- Added in version 3.2.0. +- Support for binary values (`binary_t`, `binary`) added in version 3.8.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/key.md b/json-develop/docs/mkdocs/docs/api/json_sax/key.md new file mode 100644 index 0000000..31fd6c1 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/key.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::key + +```cpp +virtual bool key(string_t& val) = 0; +``` + +An object key was read. + +## Parameters + +`val` (in) +: object key + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed object key value. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/null.md b/json-develop/docs/mkdocs/docs/api/json_sax/null.md new file mode 100644 index 0000000..9354ede --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/null.md @@ -0,0 +1,31 @@ +# nlohmann::json_sax::null + +```cpp +virtual bool null() = 0; +``` + +A null value was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/number_float.md b/json-develop/docs/mkdocs/docs/api/json_sax/number_float.md new file mode 100644 index 0000000..1779940 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/number_float.md @@ -0,0 +1,39 @@ +# nlohmann::json_sax::number_float + +```cpp +virtual bool number_float(number_float_t val, const string_t& s) = 0; +``` + +A floating-point number was read. + +## Parameters + +`val` (in) +: floating-point value + +`s` (in) +: string representation of the original input + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/number_integer.md b/json-develop/docs/mkdocs/docs/api/json_sax/number_integer.md new file mode 100644 index 0000000..5c3cb4f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/number_integer.md @@ -0,0 +1,36 @@ +# nlohmann::json_sax::number_integer + +```cpp +virtual bool number_integer(number_integer_t val) = 0; +``` + +An integer number was read. + +## Parameters + +`val` (in) +: integer value + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/number_unsigned.md b/json-develop/docs/mkdocs/docs/api/json_sax/number_unsigned.md new file mode 100644 index 0000000..0ac2500 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/number_unsigned.md @@ -0,0 +1,36 @@ +# nlohmann::json_sax::number_unsigned + +```cpp +virtual bool number_unsigned(number_unsigned_t val) = 0; +``` + +An unsigned integer number was read. + +## Parameters + +`val` (in) +: unsigned integer value + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/parse_error.md b/json-develop/docs/mkdocs/docs/api/json_sax/parse_error.md new file mode 100644 index 0000000..e41cb67 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/parse_error.md @@ -0,0 +1,44 @@ +# nlohmann::json_sax::parse_error + +```cpp +virtual bool parse_error(std::size_t position, + const std::string& last_token, + const detail::exception& ex) = 0; +``` + +A parse error occurred. + +## Parameters + +`position` (in) +: the position in the input where the error occurs + +`last_token` (in) +: the last read token + +`ex` (in) +: an exception object describing the error + +## Return value + +Whether parsing should proceed (**must return `#!cpp false`**). + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/start_array.md b/json-develop/docs/mkdocs/docs/api/json_sax/start_array.md new file mode 100644 index 0000000..cf2b8cf --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/start_array.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::start_array + +```cpp +virtual bool start_array(std::size_t elements) = 0; +``` + +The beginning of an array was read. + +## Parameters + +`elements` (in) +: number of object elements or `#!cpp -1` if unknown + +## Return value + +Whether parsing should proceed. + +## Notes + +Binary formats may report the number of elements. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/start_object.md b/json-develop/docs/mkdocs/docs/api/json_sax/start_object.md new file mode 100644 index 0000000..491815d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/start_object.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::start_object + +```cpp +virtual bool start_object(std::size_t elements) = 0; +``` + +The beginning of an object was read. + +## Parameters + +`elements` (in) +: number of object elements or `#!cpp -1` if unknown + +## Return value + +Whether parsing should proceed. + +## Notes + +Binary formats may report the number of elements. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/json_sax/string.md b/json-develop/docs/mkdocs/docs/api/json_sax/string.md new file mode 100644 index 0000000..dcffb5f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/json_sax/string.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::string + +```cpp +virtual bool string(string_t& val) = 0; +``` + +A string value was read. + +## Parameters + +`val` (in) +: string value + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed string value. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/index.md b/json-develop/docs/mkdocs/docs/api/macros/index.md new file mode 100644 index 0000000..099dfa6 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/index.md @@ -0,0 +1,60 @@ +# Macros + +Some aspects of the library can be configured by defining preprocessor macros **before** including the `json.hpp` +header. See also the [macro overview page](../../features/macros.md). + +## Runtime assertions + +- [**JSON_ASSERT(x)**](json_assert.md) - control behavior of runtime assertions + +## Exceptions + +- [**JSON_CATCH_USER(exception)**
**JSON_THROW_USER(exception)**
**JSON_TRY_USER**](json_throw_user.md) - control exceptions +- [**JSON_DIAGNOSTICS**](json_diagnostics.md) - control extended diagnostics +- [**JSON_NOEXCEPTION**](json_noexception.md) - switch off exceptions + +## Language support + +- [**JSON_HAS_CPP_11**
**JSON_HAS_CPP_14**
**JSON_HAS_CPP_17**
**JSON_HAS_CPP_20**](json_has_cpp_11.md) - set supported C++ standard +- [**JSON_HAS_FILESYSTEM**
**JSON_HAS_EXPERIMENTAL_FILESYSTEM**](json_has_filesystem.md) - control `std::filesystem` support +- [**JSON_HAS_RANGES**](json_has_ranges.md) - control `std::ranges` support +- [**JSON_HAS_THREE_WAY_COMPARISON**](json_has_three_way_comparison.md) - control 3-way comparison support +- [**JSON_NO_IO**](json_no_io.md) - switch off functions relying on certain C++ I/O headers +- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers +- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace + +## Library version + +- [**JSON_SKIP_LIBRARY_VERSION_CHECK**](json_skip_library_version_check.md) - skip library version check +- [**NLOHMANN_JSON_VERSION_MAJOR**
**NLOHMANN_JSON_VERSION_MINOR**
**NLOHMANN_JSON_VERSION_PATCH**](nlohmann_json_version_major.md) + \- library version information + +## Library namespace + +- [**NLOHMANN_JSON_NAMESPACE**](nlohmann_json_namespace.md) - full name of the `nlohmann` namespace +- [**NLOHMANN_JSON_NAMESPACE_BEGIN**
**NLOHMANN_JSON_NAMESPACE_END**](nlohmann_json_namespace_begin.md) - open and + close the library namespace +- [**NLOHMANN_JSON_NAMESPACE_NO_VERSION**](nlohmann_json_namespace_no_version.md) - disable the version component of + the inline namespace + +## Type conversions + +- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums +- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions + + +## Comparison behavior + +- [**JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON**](json_use_legacy_discarded_value_comparison.md) - + control comparison of discarded values + +## Serialization/deserialization macros + +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)**
**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)**][DefInt] + \- serialization/deserialization of types _with_ access to private variables +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)**
**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)**][DefNonInt] + \- serialization/deserialization of types _without_ access to private variables +- [**NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)**](nlohmann_json_serialize_enum.md) - serialization/deserialization of enum types + +[DefInt]: nlohmann_define_type_intrusive.md +[DefNonInt]: nlohmann_define_type_non_intrusive.md diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_assert.md b/json-develop/docs/mkdocs/docs/api/macros/json_assert.md new file mode 100644 index 0000000..a093341 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_assert.md @@ -0,0 +1,84 @@ +# JSON_ASSERT + +```cpp +#define JSON_ASSERT(x) /* value */ +``` + +This macro controls which code is executed for [runtime assertions](../../features/assertions.md) of the library. + +## Parameters + +`x` (in) +: expression of scalar type + +## Default definition + +The default value is [`#!cpp assert(x)`](https://en.cppreference.com/w/cpp/error/assert). + +```cpp +#define JSON_ASSERT(x) assert(x) +``` + +Therefore, assertions can be switched off by defining `NDEBUG`. + +## Notes + +- The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior + (e.g., when calling [operator[]](../basic_json/operator%5B%5D.md) with a missing object key on a `const` object). See + page [runtime assertions](../../features/assertions.md) for more information. +- Defining the macro to code that does not call `std::abort` may leave the library in an undefined state. +- The macro is undefined outside the library. + +## Examples + +??? example "Example 1: default behavior" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + const json j = {{"key", "value"}}; + auto v = j["missing"]; + } + ``` + + Output: + + ``` + Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144. + ``` + +??? example "Example 2: user-defined behavior" + + The assertion reporting can be changed by defining `JSON_ASSERT(x)` differently. + + ```cpp + #include + #include + #define JSON_ASSERT(x) if(!(x)){fprintf(stderr, "assertion error in %s\n", __FUNCTION__); std::abort();} + + #include + + using json = nlohmann::json; + + int main() + { + const json j = {{"key", "value"}}; + auto v = j["missing"]; + } + ``` + + Output: + + ``` + assertion error in operator[] + ``` + +## Version history + +- Added in version 3.9.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_diagnostics.md b/json-develop/docs/mkdocs/docs/api/macros/json_diagnostics.md new file mode 100644 index 0000000..4fc0fc3 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_diagnostics.md @@ -0,0 +1,76 @@ +# JSON_DIAGNOSTICS + +```cpp +#define JSON_DIAGNOSTICS /* value */ +``` + +This macro enables [extended diagnostics for exception messages](../../home/exceptions.md#extended-diagnostic-messages). +Possible values are `1` to enable or `0` to disable (default). + +When enabled, exception messages contain a [JSON Pointer](../json_pointer/json_pointer.md) to the JSON value that +triggered the exception. Note that enabling this macro increases the size of every JSON value by one pointer and adds +some runtime overhead. + +## Default definition + +The default value is `0` (extended diagnostics are switched off). + +```cpp +#define JSON_DIAGNOSTICS 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! note "ABI compatibility" + + As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid + One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct + symbol names. + + This allows different parts of a codebase to use different versions or configurations of this library without + causing improper behavior. + + Where possible, it is still recommended that all code define this the same way for maximum interoperability. + +!!! hint "CMake option" + + Diagnostic messages can also be controlled with the CMake option + [`JSON_Diagnostics`](../../integration/cmake.md#json_diagnostics) (`OFF` by default) + which defines `JSON_DIAGNOSTICS` accordingly. + +## Examples + +??? example "Example 1: default behavior" + + ```cpp + --8<-- "examples/diagnostics_standard.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_standard.output" + ``` + + This exception can be hard to debug if storing the value `#!c "12"` and accessing it is further apart. + +??? example "Example 2: extended diagnostic messages" + + ```cpp + --8<-- "examples/diagnostics_extended.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_extended.output" + ``` + + Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type. + +## Version history + +- Added in version 3.10.0. +- As of version 3.11.0 the definition is allowed to vary between translation units. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_disable_enum_serialization.md b/json-develop/docs/mkdocs/docs/api/macros/json_disable_enum_serialization.md new file mode 100644 index 0000000..6df3dd5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_disable_enum_serialization.md @@ -0,0 +1,152 @@ +# JSON_DISABLE_ENUM_SERIALIZATION + +```cpp +#define JSON_DISABLE_ENUM_SERIALIZATION /* value */ +``` + +When defined to `1`, default serialization and deserialization functions for enums are excluded and have to be provided +by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) (see +[arbitrary type conversions](../../features/arbitrary_types.md) for more details). + +Parsing or serializing an enum will result in a compiler error. + +This works for both unscoped and scoped enums. + +## Default definition + +The default value is `0`. + +```cpp +#define JSON_DISABLE_ENUM_SERIALIZATION 0 +``` + +## Notes + +!!! hint "CMake option" + + Enum serialization can also be controlled with the CMake option + [`JSON_DisableEnumSerialization`](../../integration/cmake.md#json_disableenumserialization) + (`OFF` by default) which defines `JSON_DISABLE_ENUM_SERIALIZATION` accordingly. + +## Examples + +??? example "Example 1: Disabled behavior" + + The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, meaning the code below + **does not** compile. + + ```cpp + #define JSON_DISABLE_ENUM_SERIALIZATION 1 + #include + + using json = nlohmann::json; + + enum class Choice + { + first, + second, + }; + + int main() + { + // normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not + const json j = Choice::first; + + // normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not + Choice ch = j.get(); + } + ``` + +??? example "Example 2: Serialize enum macro" + + The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses + [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) to parse and serialize the enum. + + ```cpp + #define JSON_DISABLE_ENUM_SERIALIZATION 1 + #include + + using json = nlohmann::json; + + enum class Choice + { + first, + second, + }; + + NLOHMANN_JSON_SERIALIZE_ENUM(Choice, + { + { Choice::first, "first" }, + { Choice::second, "second" }, + }) + + int main() + { + // uses user-defined to_json function defined by macro + const json j = Choice::first; + + // uses user-defined from_json function defined by macro + Choice ch = j.get(); + } + ``` + +??? example "Example 3: User-defined serialization/deserialization functions" + + The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses user-defined + functions to parse and serialize the enum. + + ```cpp + #define JSON_DISABLE_ENUM_SERIALIZATION 1 + #include + + using json = nlohmann::json; + + enum class Choice + { + first, + second, + }; + + void from_json(const json& j, Choice& ch) + { + auto value = j.get(); + if (value == "first") + { + ch = Choice::first; + } + else if (value == "second") + { + ch = Choice::second; + } + } + + void to_json(json& j, const Choice& ch) + { + auto value = j.get(); + if (value == "first") + { + ch = Choice::first; + } + else if (value == "second") + { + ch = Choice::second; + } + } + + int main() + { + // uses user-defined to_json function + const json j = Choice::first; + + // uses user-defined from_json function + Choice ch = j.get(); + } + ``` + +## See also + +- [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_has_cpp_11.md b/json-develop/docs/mkdocs/docs/api/macros/json_has_cpp_11.md new file mode 100644 index 0000000..f3eaa58 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_has_cpp_11.md @@ -0,0 +1,41 @@ +# JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20 + +```cpp +#define JSON_HAS_CPP_11 +#define JSON_HAS_CPP_14 +#define JSON_HAS_CPP_17 +#define JSON_HAS_CPP_20 +``` + +The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` +support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ +standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is +unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be +detected incorrectly. + +## Default definition + +The default value is detected based on preprocessor macros such as `#!cpp __cplusplus`, `#!cpp _HAS_CXX17`, or +`#!cpp _MSVC_LANG`. + +## Notes + +- `#!cpp JSON_HAS_CPP_11` is always defined. +- All macros are undefined outside the library. + +## Examples + +??? example + + The code below forces the library to use the C++14 standard: + + ```cpp + #define JSON_HAS_CPP_14 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.10.5. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_has_filesystem.md b/json-develop/docs/mkdocs/docs/api/macros/json_has_filesystem.md new file mode 100644 index 0000000..308aea2 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_has_filesystem.md @@ -0,0 +1,43 @@ +# JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM + +```cpp +#define JSON_HAS_FILESYSTEM /* value */ +#define JSON_HAS_EXPERIMENTAL_FILESYSTEM /* value */ +``` + +When compiling with C++17, the library provides conversions from and to +[`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path). As compiler support for filesystem is +limited, the library tries to detect whether +[``/`std::filesystem`](https://en.cppreference.com/w/cpp/header/filesystem) (`JSON_HAS_FILESYSTEM`) or +[``/`std::experimental::filesystem`](https://en.cppreference.com/w/cpp/header/experimental/filesystem) +(`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used. To override the built-in check, define `JSON_HAS_FILESYSTEM` or +`JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`. + +## Default definition + +The default value is detected based on the preprocessor macros `#!cpp __cpp_lib_filesystem`, +`#!cpp __cpp_lib_experimental_filesystem`, `#!cpp __has_include()`, or +`#!cpp __has_include()`. + +## Notes + +- Note that older compilers or older versions of libstd++ also require the library `stdc++fs` to be linked to for + filesystem support. +- Both macros are undefined outside the library. + +## Examples + +??? example + + The code below forces the library to use the header ``. + + ```cpp + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.10.5. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_has_ranges.md b/json-develop/docs/mkdocs/docs/api/macros/json_has_ranges.md new file mode 100644 index 0000000..96d5105 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_has_ranges.md @@ -0,0 +1,31 @@ +# JSON_HAS_RANGES + +```cpp +#define JSON_HAS_RANGES /* value */ +``` + +This macro indicates whether the standard library has any support for ranges. Implies support for concepts. +Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macro `#!cpp __cpp_lib_ranges`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The code below forces the library to enable support for ranges: + + ```cpp + #define JSON_HAS_RANGES 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_has_three_way_comparison.md b/json-develop/docs/mkdocs/docs/api/macros/json_has_three_way_comparison.md new file mode 100644 index 0000000..f52070e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_has_three_way_comparison.md @@ -0,0 +1,32 @@ +# JSON_HAS_THREE_WAY_COMPARISON + +```cpp +#define JSON_HAS_THREE_WAY_COMPARISON /* value */ +``` + +This macro indicates whether the compiler and standard library support 3-way comparison. +Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macros `#!cpp __cpp_impl_three_way_comparison` +and `#!cpp __cpp_lib_three_way_comparison`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The code below forces the library to use 3-way comparison: + + ```cpp + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_no_io.md b/json-develop/docs/mkdocs/docs/api/macros/json_no_io.md new file mode 100644 index 0000000..ef37384 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_no_io.md @@ -0,0 +1,35 @@ +# JSON_NO_IO + +```cpp +#define JSON_NO_IO +``` + +When defined, headers ``, ``, ``, ``, and `` are not included and parse functions +relying on these headers are excluded. This is relevant for environments where these I/O functions are disallowed for +security reasons (e.g., Intel Software Guard Extensions (SGX)). + +## Default definition + +By default, `#!cpp JSON_NO_IO` is not defined. + +```cpp +#undef JSON_NO_IO +``` + +## Examples + +??? example + + The code below forces the library not to use the headers ``, ``, ``, ``, and + ``. + + ```cpp + #define JSON_NO_IO 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.10.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_noexception.md b/json-develop/docs/mkdocs/docs/api/macros/json_noexception.md new file mode 100644 index 0000000..c801b85 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_noexception.md @@ -0,0 +1,45 @@ +# JSON_NOEXCEPTION + +```cpp +#define JSON_NOEXCEPTION +``` + +Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. When defining `JSON_NOEXCEPTION`, `#!cpp try` +is replaced by `#!cpp if (true)`, `#!cpp catch` is replaced by `#!cpp if (false)`, and `#!cpp throw` is replaced by +`#!cpp std::abort()`. + +The same effect is achieved by setting the compiler flag `-fno-exceptions`. + +## Default definition + +By default, the macro is not defined. + +```cpp +#undef JSON_NOEXCEPTION +``` + +## Notes + +The explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not +available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +## Examples + +??? example + + The code below switches off exceptions in the library. + + ```cpp + #define JSON_NOEXCEPTION 1 + #include + + ... + ``` + +## See also + +- [Switch off exceptions](../../home/exceptions.md#switch-off-exceptions) for more information how to switch off exceptions + +## Version history + +Added in version 2.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_skip_library_version_check.md b/json-develop/docs/mkdocs/docs/api/macros/json_skip_library_version_check.md new file mode 100644 index 0000000..c9a743c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_skip_library_version_check.md @@ -0,0 +1,37 @@ +# JSON_SKIP_LIBRARY_VERSION_CHECK + +```cpp +#define JSON_SKIP_LIBRARY_VERSION_CHECK +``` + +When defined, the library will not create a compiler warning when a different version of the library was already +included. + +## Default definition + +By default, the macro is not defined. + +```cpp +#undef JSON_SKIP_LIBRARY_VERSION_CHECK +``` + +## Notes + +!!! danger "ABI compatibility" + + Mixing different library versions in the same code can be a problem as the different versions may not be ABI + compatible. + +## Examples + +!!! example + + The following warning will be shown in case a different version of the library was already included: + + ``` + Already included a different version of the library! + ``` + +## Version history + +Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_skip_unsupported_compiler_check.md b/json-develop/docs/mkdocs/docs/api/macros/json_skip_unsupported_compiler_check.md new file mode 100644 index 0000000..374fa4c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_skip_unsupported_compiler_check.md @@ -0,0 +1,33 @@ +# JSON_SKIP_UNSUPPORTED_COMPILER_CHECK + +```cpp +#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK +``` + +When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to +use the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. + +## Default definition + +By default, the macro is not defined. + +```cpp +#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK +``` + +## Examples + +??? example + + The code below switches off the check whether the compiler is supported. + + ```cpp + #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1 + #include + + ... + ``` + +## Version history + +Added in version 3.2.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_throw_user.md b/json-develop/docs/mkdocs/docs/api/macros/json_throw_user.md new file mode 100644 index 0000000..e10db90 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_throw_user.md @@ -0,0 +1,75 @@ +# JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER + +```cpp +// (1) +#define JSON_CATCH_USER(exception) /* value */ +// (2) +#define JSON_THROW_USER(exception) /* value */ +// (3) +#define JSON_TRY_USER /* value */ +``` + +Controls how exceptions are handled by the library. + +1. This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library. + The argument is the type of the exception to catch. As of version 3.8.0, the library only catches `std::out_of_range` + exceptions internally to rethrow them as [`json::out_of_range`](../../home/exceptions.md#out-of-range) exceptions. + The macro is always followed by a scope. +2. This macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. Note that + `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield + undefined behavior. +3. This macro overrides `#!cpp try` calls inside the library. It has no arguments and is always followed by a scope. + +## Parameters + +`exception` (in) +: an exception type + +## Default definition + +By default, the macros map to their respective C++ keywords: + +```cpp +#define JSON_CATCH_USER(exception) catch(exception) +#define JSON_THROW_USER(exception) throw exception +#define JSON_TRY_USER try +``` + +When exceptions are switched off, the `#!cpp try` block is executed unconditionally, and throwing exceptions is +replaced by calling [`std::abort`](https://en.cppreference.com/w/cpp/utility/program/abort) to make reaching the +`#!cpp throw` branch abort the process. + +```cpp +#define JSON_THROW_USER(exception) std::abort() +#define JSON_TRY_USER if (true) +#define JSON_CATCH_USER(exception) if (false) +``` + +## Examples + +??? example + + The code below switches off exceptions and creates a log entry with a detailed error message in case of errors. + + ```cpp + #include + + #define JSON_TRY_USER if(true) + #define JSON_CATCH_USER(exception) if(false) + #define JSON_THROW_USER(exception) \ + {std::clog << "Error in " << __FILE__ << ":" << __LINE__ \ + << " (function " << __FUNCTION__ << ") - " \ + << (exception).what() << std::endl; \ + std::abort();} + + #include + ``` + +## See also + +- [Switch off exceptions](../../home/exceptions.md#switch-off-exceptions) for more information how to switch off exceptions +- [JSON_NOEXCEPTION](JSON_NOEXCEPTION) - switch off exceptions + +## Version history + +- Added in version 3.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_use_global_udls.md b/json-develop/docs/mkdocs/docs/api/macros/json_use_global_udls.md new file mode 100644 index 0000000..69db9e7 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_use_global_udls.md @@ -0,0 +1,98 @@ +# JSON_USE_GLOBAL_UDLS + +```cpp +#define JSON_USE_GLOBAL_UDLS /* value */ +``` + +When defined to `1`, the user-defined string literals (UDLs) are placed into the global namespace instead of +`nlohmann::literals::json_literals`. + +## Default definition + +The default value is `1`. + +```cpp +#define JSON_USE_GLOBAL_UDLS 1 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! info "Future behavior change" + + The user-defined string literals will be removed from the global namespace in the next major release of the library. + + To prepare existing code, define `JSON_USE_GLOBAL_UDLS` to `0` and bring the string literals into scope where + needed. Refer to any of the [string literals](#see-also) for details. + +!!! hint "CMake option" + + The placement of user-defined string literals can also be controlled with the CMake option + [`JSON_GlobalUDLs`](../../integration/cmake.md#json_globaludls) (`ON` by default) which defines + `JSON_USE_GLOBAL_UDLS` accordingly. + +## Examples + +??? example "Example 1: Default behavior" + + The code below shows the default behavior using the `_json` UDL. + + ```cpp + #include + + #include + + int main() + { + auto j = "42"_json; + + std::cout << j << std::endl; + } + ``` + + Output: + + ```json + 42 + ``` + +??? example "Example 2: Namespaced UDLs" + + The code below shows how UDLs need to be brought into scope before using `_json` when `JSON_USE_GLOBAL_UDLS` is + defined to `0`. + + ```cpp + #define JSON_USE_GLOBAL_UDLS 0 + #include + + #include + + int main() + { + // auto j = "42"_json; // This line would fail to compile, + // because the UDLs are not in the global namespace + + // Bring the UDLs into scope + using namespace nlohmann::json_literals; + + auto j = "42"_json; + + std::cout << j << std::endl; + } + ``` + + Output: + + ```json + 42 + ``` + +## See also + +- [`operator""_json`](../operator_literal_json.md) +- [`operator""_json_pointer`](../operator_literal_json_pointer.md) + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md b/json-develop/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md new file mode 100644 index 0000000..adadffa --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md @@ -0,0 +1,59 @@ +# JSON_USE_IMPLICIT_CONVERSIONS + +```cpp +#define JSON_USE_IMPLICIT_CONVERSIONS /* value */ +``` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. The +value directly affects [`operator ValueType`](../basic_json/operator_ValueType.md). + +## Default definition + +By default, implicit conversions are enabled. + +```cpp +#define JSON_USE_IMPLICIT_CONVERSIONS 1 +``` + +## Notes + +!!! info "Future behavior change" + + Implicit conversions will be switched off by default in the next major release of the library. + + You can prepare existing code by already defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` and replace any implicit + conversions with calls to [`get`](../basic_json/get.md). + +!!! hint "CMake option" + + Implicit conversions can also be controlled with the CMake option + [`JSON_ImplicitConversions`](../../integration/cmake.md#json_legacydiscardedvaluecomparison) + (`ON` by default) which defines `JSON_USE_IMPLICIT_CONVERSIONS` accordingly. + +## Examples + +??? example + + This is an example for an implicit conversion: + + ```cpp + json j = "Hello, world!"; + std::string s = j; + ``` + + When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be + written like this: + + ```cpp + json j = "Hello, world!"; + auto s = j.get(); + ``` + +## See also + +- [**operator ValueType**](../basic_json/operator_ValueType.md) - get a value (implicit) +- [**get**](../basic_json/get.md) - get a value (explicit) + +## Version history + +- Added in version 3.9.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/json_use_legacy_discarded_value_comparison.md b/json-develop/docs/mkdocs/docs/api/macros/json_use_legacy_discarded_value_comparison.md new file mode 100644 index 0000000..bc1d143 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/json_use_legacy_discarded_value_comparison.md @@ -0,0 +1,77 @@ +# JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + +```cpp +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON /* value */ +``` + +This macro enables the (incorrect) legacy comparison behavior of discarded JSON values. Possible values are `1` to +enable or `0` to disable (default). + +When enabled, comparisons involving at least one discarded JSON value yield results as follows: + +| **Operator** | **Result** | +|--------------|---------------| +| `==` | `#!cpp false` | +| `!=` | `#!cpp true` | +| `<` | `#!cpp false` | +| `<=` | `#!cpp true` | +| `>=` | `#!cpp true` | +| `>` | `#!cpp false` | + +Otherwise, comparisons involving at least one discarded JSON value always yield `#!cpp false`. + +## Default definition + +The default value is `0`. + +```cpp +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! warning "Inconsistent behavior in C++20 and beyond" + + When targeting C++20 or above, enabling the legacy comparison behavior is _strongly_ + discouraged. + + - The 3-way comparison operator (`<=>`) will always give the correct result + (`#!cpp std::partial_ordering::unordered`) regardless of the value of + `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`. + - Overloads for the equality and relational operators emulate the legacy behavior. + + Code outside your control may use either 3-way comparison or the equality and relational operators, resulting in + inconsistent and unpredictable behavior. + + See [`operator<=>`](../basic_json/operator_spaceship.md) for more information on 3-way comparison. + +!!! warning "Deprecation" + + The legacy comparison behavior is deprecated and may be removed in a future major version release. + + New code should not depend on it and existing code should try to remove or rewrite expressions relying on it. + +!!! hint "CMake option" + + Legacy comparison can also be controlled with the CMake option + [`JSON_LegacyDiscardedValueComparison`](../../integration/cmake.md#json_legacydiscardedvaluecomparison) + (`OFF` by default) which defines `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON` accordingly. + +## Examples + +??? example + + The code below switches on the legacy discarded value comparison behavior in the library. + + ```cpp + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md new file mode 100644 index 0000000..afd09c6 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md @@ -0,0 +1,126 @@ +# NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT + +```cpp +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) +``` + +These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as +serialization and want to use the member variable names as object keys in that object. The macro is to be defined +**inside** the class/struct to create code for. Unlike +[`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](nlohmann_define_type_non_intrusive.md), it can access private members. The first +parameter is the name of the class/struct, and all remaining parameters name the members. + +1. Will use [`at`](../basic_json/at.md) during deserialization and will throw + [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object. +2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the + respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function + default constructs an object and uses its values as the defaults when calling the `value` function. + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`member` (in) +: name of the member variable to serialize/deserialize; up to 64 members can be given as comma-separated list + +## Default definition + +The macros add two friend functions to the class which take care of the serialization and deserialization: + +```cpp +friend void to_json(nlohmann::json&, const type&); +friend void from_json(const nlohmann::json&, type&); +``` + +See examples below for the concrete generated code. + +## Notes + +!!! info "Prerequisites" + + 1. The type `type` must be default constructible. See [How can I use `get()` for non-default + constructible/non-copyable types?][GetNonDefNonCopy] for how to overcome this limitation. + 2. The macro must be used inside the type (class/struct). + +[GetNonDefNonCopy]: ../../features/arbitrary_types.md#how-can-i-use-get-for-non-default-constructiblenon-copyable-types + +!!! warning "Implementation limits" + + - The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types + with more than 64 member variables, you need to define the `to_json`/`from_json` functions manually. + - The macros only work for the [`nlohmann::json`](../json.md) type; other specializations such as + [`nlohmann::ordered_json`](../ordered_json.md) are currently unsupported. + +## Examples + +??? example "Example (1): NLOHMANN_DEFINE_TYPE_INTRUSIVE" + + Consider the following complete example: + + ```cpp hl_lines="21" + --8<-- "examples/nlohmann_define_type_intrusive_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_intrusive_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE` applicable, but not + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`. + - The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is used _inside_ the class. + - A missing key "age" in the deserialization yields an exception. To fall back to the default value, + `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` can be used. + + The macro is equivalent to: + + ```cpp hl_lines="21 22 23 24 25 26 27 28 29 30 31 32 33" + --8<-- "examples/nlohmann_define_type_intrusive_explicit.cpp" + ``` + +??? example "Example (2): NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT" + + Consider the following complete example: + + ```cpp hl_lines="21" + --8<-- "examples/nlohmann_define_type_intrusive_with_default_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_intrusive_with_default_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` applicable, + but not `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. + - The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` is used _inside_ the class. + - A missing key "age" in the deserialization does not yield an exception. Instead, the default value `-1` is used. + + The macro is equivalent to: + + ```cpp hl_lines="21 22 23 24 25 26 27 28 29 30 31 32 33 34" + --8<-- "examples/nlohmann_define_type_intrusive_with_default_explicit.cpp" + ``` + + Note how a default-initialized `person` object is used in the `from_json` to fill missing values. + +## See also + +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_non_intrusive.md) + for a similar macro that can be defined _outside_ the type. +- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. + +## Version history + +1. Added in version 3.9.0. +2. Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md new file mode 100644 index 0000000..70cf934 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md @@ -0,0 +1,127 @@ +# NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT + +```cpp +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) +``` + +These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as +serialization and want to use the member variable names as object keys in that object. The macro is to be defined +**outside** the class/struct to create code for, but **inside** its namespace. Unlike +[`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](nlohmann_define_type_intrusive.md), it **cannot** access private members. The first +parameter is the name of the class/struct, and all remaining parameters name the members. + +1. Will use [`at`](../basic_json/at.md) during deserialization and will throw + [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object. +2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the + respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function + default constructs an object and uses its values as the defaults when calling the `value` function. + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`member` (in) +: name of the (public) member variable to serialize/deserialize; up to 64 members can be given as comma-separated list + +## Default definition + +The macros add two functions to the namespace which take care of the serialization and deserialization: + +```cpp +void to_json(nlohmann::json&, const type&); +void from_json(const nlohmann::json&, type&); +``` + +See examples below for the concrete generated code. + +## Notes + +!!! info "Prerequisites" + + 1. The type `type` must be default constructible. See [How can I use `get()` for non-default constructible/non-copyable types?][GetNonDefNonCopy] + for how to overcome this limitation. + 2. The macro must be used outside the type (class/struct). + 3. The passed members must be public. + +[GetNonDefNonCopy]: ../../features/arbitrary_types.md#how-can-i-use-get-for-non-default-constructiblenon-copyable-types + +!!! warning "Implementation limits" + + - The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types + with more than 64 member variables, you need to define the `to_json`/`from_json` functions manually. + - The macros only work for the [`nlohmann::json`](../json.md) type; other specializations such as + [`nlohmann::ordered_json`](../ordered_json.md) are currently unsupported. + +## Examples + +??? example "Example (1): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE" + + Consider the following complete example: + + ```cpp hl_lines="15" + --8<-- "examples/nlohmann_define_type_non_intrusive_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_non_intrusive_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` applicable. + - The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` is used _outside_ the class, but _inside_ its namespace `ns`. + - A missing key "age" in the deserialization yields an exception. To fall back to the default value, + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` can be used. + + The macro is equivalent to: + + ```cpp hl_lines="15 16 17 18 19 20 21 22 23 24 25 26 27" + --8<-- "examples/nlohmann_define_type_non_intrusive_explicit.cpp" + ``` + +??? example "Example (2): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT" + + Consider the following complete example: + + ```cpp hl_lines="20" + --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` + applicable. + - The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` is used _outside_ the class, but _inside_ its + namespace `ns`. + - A missing key "age" in the deserialization does not yield an exception. Instead, the default value `-1` is used. + + The macro is equivalent to: + + ```cpp hl_lines="20 21 22 23 24 25 26 27 28 29 30 31 32 33" + --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp" + ``` + + Note how a default-initialized `person` object is used in the `from_json` to fill missing values. + +## See also + +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_intrusive.md) + for a similar macro that can be defined _inside_ the type. +- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. + +## Version history + +1. Added in version 3.9.0. +2. Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md new file mode 100644 index 0000000..5c54dba --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md @@ -0,0 +1,41 @@ +# NLOHMANN_JSON_NAMESPACE + +```cpp +#define NLOHMANN_JSON_NAMESPACE /* value */ +``` + +This macro evaluates to the full name of the `nlohmann` namespace. + +## Default definition + +The default value consists of the root namespace (`nlohmann`) and an inline ABI namespace. See +[`nlohmann` Namespace](../../features/namespace.md#structure) for details. + +When the macro is not defined, the library will define it to its default value. Overriding this value has no effect on +the library. + +## Examples + +??? example + + The example shows how to use `NLOHMANN_JSON_NAMESPACE` instead of just `nlohmann`, as well as how to output the value + of `NLOHMANN_JSON_NAMESPACE`. + + ```cpp + --8<-- "examples/nlohmann_json_namespace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_namespace.output" + ``` + +## See also + +- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md) +- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](nlohmann_json_namespace_no_version.md) + +## Version history + +- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md new file mode 100644 index 0000000..1374264 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md @@ -0,0 +1,61 @@ +# NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END + +```cpp +#define NLOHMANN_JSON_NAMESPACE_BEGIN /* value */ // (1) +#define NLOHMANN_JSON_NAMESPACE_END /* value */ // (2) +``` + +These macros can be used to open and close the `nlohmann` namespace. See +[`nlohmann` Namespace](../../features/namespace.md#structure) for details. + +1. Opens the namespace. +2. Closes the namespace. + +## Default definition + +The default definitions open and close the `nlohmann` namespace. The precise definition of +[`NLOHMANN_JSON_NAMESPACE_BEGIN`] varies as described [here](../../features/namespace.md#structure). + +1. Default definition of `NLOHMANN_JSON_NAMESPACE_BEGIN`: + + ```cpp + namespace nlohmann + { + inline namespace json_abi_v3_11_2 + { + ``` + +2. Default definition of `NLOHMANN_JSON_NAMESPACE_END`: + ```cpp + } // namespace json_abi_v3_11_2 + } // namespace nlohmann + ``` + +When these macros are not defined, the library will define them to their default definitions. + +## Examples + +??? example + + The example shows how to use `NLOHMANN_JSON_NAMESPACE_BEGIN`/`NLOHMANN_JSON_NAMESPACE_END` from the + [How do I convert third-party types?](../../features/arbitrary_types.md#how-do-i-convert-third-party-types) page. + + ```cpp + --8<-- "examples/nlohmann_json_namespace_begin.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_namespace_begin.c++17.output" + ``` + +## See also + +- [`nlohmann` Namespace](../../features/namespace.md) +- [NLOHMANN_JSON_NAMESPACE](nlohmann_json_namespace.md) +- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](nlohmann_json_namespace_no_version.md) + +## Version history + +- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_no_version.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_no_version.md new file mode 100644 index 0000000..9e2a52d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_no_version.md @@ -0,0 +1,45 @@ +# NLOHMANN_JSON_NAMESPACE_NO_VERSION + +```cpp +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */ +``` + +If defined to `1`, the version component is omitted from the inline namespace. See +[`nlohmann` Namespace](../../features/namespace.md#structure) for details. + +## Default definition + +The default value is `0`. + +```cpp +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The example shows how to use `NLOHMANN_JSON_NAMESPACE_NO_VERSION` to disable the version component of the inline + namespace. + + ```cpp + --8<-- "examples/nlohmann_json_namespace_no_version.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_namespace_no_version.output" + ``` + +## See also + +- [`nlohmann` Namespace](../../features/namespace.md) +- [`NLOHMANN_JSON_NAMESPACE`](nlohmann_json_namespace.md) +- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md) + +## Version history + +- Added in version 3.11.2. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md new file mode 100644 index 0000000..c28765a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md @@ -0,0 +1,85 @@ +# NLOHMANN_JSON_SERIALIZE_ENUM + +```cpp +#define NLOHMANN_JSON_SERIALIZE_ENUM(type, conversion...) +``` + +By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an +enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be +undefined or a different enum value than was originally intended. + +The `NLOHMANN_JSON_SERIALIZE_ENUM` allows to define a user-defined serialization for every enumerator. + +## Parameters + +`type` (in) +: name of the enum to serialize/deserialize + +`conversion` (in) +: a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list + +## Default definition + +The macros add two friend functions to the class which take care of the serialization and deserialization: + +```cpp +template +inline void to_json(BasicJsonType& j, const type& e); +template +inline void from_json(const BasicJsonType& j, type& e); +``` + +## Notes + +!!! info "Prerequisites" + + The macro must be used inside the namespace of the enum. + +!!! important "Important notes" + + - When using [`get()`](../basic_json/get.md), undefined JSON values will default to the first specified + conversion. Select this default pair carefully. See example 1 below. + - If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the + list will be returned when converting to or from JSON. See example 2 below. + +## Examples + +??? example "Example 1: Basic usage" + + The example shows how `NLOHMANN_JSON_SERIALIZE_ENUM` can be used to serialize/deserialize both classical enums and + C++11 enum classes: + + ```cpp hl_lines="16 17 18 19 20 21 22 29 30 31 32 33" + --8<-- "examples/nlohmann_json_serialize_enum.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_serialize_enum.output" + ``` + +??? example "Example 2: Multiple conversions for one enumerator" + + The example shows how to use multiple conversions for a single enumerator. In the example, `Color::red` will always + be *serialized* to `"red"`, because the first occurring conversion. The second conversion, however, offers an + alternative *deserialization* from `"rot"` to `Color::red`. + + ```cpp hl_lines="17" + --8<-- "examples/nlohmann_json_serialize_enum_2.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_serialize_enum_2.output" + ``` + +## See also + +- [Specializing enum conversion](../../features/enum_conversion.md) +- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md) + +## Version history + +Added in version 3.4.0. diff --git a/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_version_major.md b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_version_major.md new file mode 100644 index 0000000..d7a3142 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/macros/nlohmann_json_version_major.md @@ -0,0 +1,40 @@ +# NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH + +```cpp +#define NLOHMANN_JSON_VERSION_MAJOR /* value */ +#define NLOHMANN_JSON_VERSION_MINOR /* value */ +#define NLOHMANN_JSON_VERSION_PATCH /* value */ +``` + +These macros are defined by the library and contain the version numbers according to +[Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +## Default definition + +The macros are defined according to the current library version. + +## Examples + +??? example + + The example below shows how `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and + `NLOHMANN_JSON_VERSION_PATCH` are defined by the library. + + ```cpp + --8<-- "examples/nlohmann_json_version.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_version.output" + ``` + +## See also + +- [meta](../basic_json/meta.md) - returns version information on the library +- [JSON_SKIP_LIBRARY_VERSION_CHECK](json_skip_library_version_check.md) - skip library version check + +## Version history + +- Added in version 3.1.0. diff --git a/json-develop/docs/mkdocs/docs/api/operator_gtgt.md b/json-develop/docs/mkdocs/docs/api/operator_gtgt.md new file mode 100644 index 0000000..e76cc0d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/operator_gtgt.md @@ -0,0 +1,64 @@ +# nlohmann::operator>>(basic_json) + +```cpp +std::istream& operator>>(std::istream& i, basic_json& j); +``` + +Deserializes an input stream to a JSON value. + +## Parameters + +`i` (in, out) +: input stream to read a serialized JSON value from + +`j` (in, out) +: JSON value to write the deserialized input to + +## Return value + +the stream `i` + +## Exceptions + +- Throws [`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token. +- Throws [`parse_error.102`](../home/exceptions.md#jsonexceptionparse_error102) if to_unicode fails or surrogate error. +- Throws [`parse_error.103`](../home/exceptions.md#jsonexceptionparse_error103) if to_unicode fails. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +!!! warning "Deprecation" + + This function replaces function `#!cpp std::istream& operator<<(basic_json& j, std::istream& i)` which has + been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j << i;` + with `#!cpp i >> j;`. + +## Examples + +??? example + + The example below shows how a JSON value is constructed by reading a serialization from a stream. + + ```cpp + --8<-- "examples/operator_deserialize.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_deserialize.output" + ``` + +## See also + +- [accept](basic_json/accept.md) - check if the input is valid JSON +- [parse](basic_json/parse.md) - deserialize from a compatible input + +## Version history + +- Added in version 1.0.0. Deprecated in version 3.0.0. diff --git a/json-develop/docs/mkdocs/docs/api/operator_literal_json.md b/json-develop/docs/mkdocs/docs/api/operator_literal_json.md new file mode 100644 index 0000000..cda0021 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/operator_literal_json.md @@ -0,0 +1,61 @@ +# nlohmann::operator""_json + +```cpp +json operator "" _json(const char* s, std::size_t n); +``` + +This operator implements a user-defined string literal for JSON objects. It can be used by adding `#!cpp _json` to a +string literal and returns a [`json`](json.md) object if no parse error occurred. + +It is recommended to bring the operator into scope using any of the following lines: +```cpp +using nlohmann::literals::operator "" _json; +using namespace nlohmann::literals; +using namespace nlohmann::json_literals; +using namespace nlohmann::literals::json_literals; +using namespace nlohmann; +``` + +This is suggested to ease migration to the next major version release of the library. See +['JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. + +## Parameters + +`s` (in) +: a string representation of a JSON object + +`n` (in) +: length of string `s` + +## Return value + +[`json`](json.md) value parsed from `s` + +## Exceptions + +The function can throw anything that [`parse(s, s+n)`](basic_json/parse.md) would throw. + +## Complexity + +Linear. + +## Examples + +??? example + + The following code shows how to create JSON values from string literals. + + ```cpp + --8<-- "examples/operator_literal_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_literal_json.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/operator_literal_json_pointer.md b/json-develop/docs/mkdocs/docs/api/operator_literal_json_pointer.md new file mode 100644 index 0000000..14d5378 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/operator_literal_json_pointer.md @@ -0,0 +1,64 @@ +# nlohmann::operator""_json_pointer + +```cpp +json_pointer operator "" _json_pointer(const char* s, std::size_t n); +``` + +This operator implements a user-defined string literal for JSON Pointers. It can be used by adding `#!cpp _json_pointer` +to a string literal and returns a [`json_pointer`](json_pointer/index.md) object if no parse error occurred. + +It is recommended to bring the operator into scope using any of the following lines: +```cpp +using nlohmann::literals::operator "" _json_pointer; +using namespace nlohmann::literals; +using namespace nlohmann::json_literals; +using namespace nlohmann::literals::json_literals; +using namespace nlohmann; +``` +This is suggested to ease migration to the next major version release of the library. See +['JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. + +## Parameters + +`s` (in) +: a string representation of a JSON Pointer + +`n` (in) +: length of string `s` + +## Return value + +[`json_pointer`](json_pointer/index.md) value parsed from `s` + +## Exceptions + +The function can throw anything that [`json_pointer::json_pointer`](json_pointer/index.md) would throw. + +## Complexity + +Linear. + +## Examples + +??? example + + The following code shows how to create JSON Pointers from string literals. + + ```cpp + --8<-- "examples/operator_literal_json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_literal_json_pointer.output" + ``` + +## See also + +- [json_pointer](json_pointer/index.md) - type to represent JSON Pointers + +## Version history + +- Added in version 2.0.0. +- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/operator_ltlt.md b/json-develop/docs/mkdocs/docs/api/operator_ltlt.md new file mode 100644 index 0000000..1718b3c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/operator_ltlt.md @@ -0,0 +1,87 @@ +# nlohmann::operator<<(basic_json), nlohmann::operator<<(json_pointer) + +```cpp +std::ostream& operator<<(std::ostream& o, const basic_json& j); // (1) + +std::ostream& operator<<(std::ostream& o, const json_pointer& ptr); // (2) +``` + +1. Serialize the given JSON value `j` to the output stream `o`. The JSON value will be serialized using the + [`dump`](basic_json/dump.md) member function. + - The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For + instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4` and the serialization + result is the same as calling `dump(4)`. + - The indentation character can be controlled with the member variable `fill` of the output stream `o`. + For instance, the manipulator `std::setfill('\\t')` sets indentation to use a tab character rather than the + default space character. +2. Write a string representation of the given JSON pointer `ptr` to the output stream `o`. The string representation is + obtained using the [`to_string`](json_pointer/to_string.md) member function. + +## Parameters + +`o` (in, out) +: stream to write to + +`j` (in) +: JSON value to serialize + +`ptr` (in) +: JSON pointer to write + +## Return value + +the stream `o` + +## Exceptions + +1. Throws [`type_error.316`](../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON + value is not UTF-8 encoded. Note that unlike the [`dump`](basic_json/dump.md) member functions, no `error_handler` + can be set. +2. None. + +## Complexity + +Linear. + +## Notes + +!!! warning "Deprecation" + + Function `#!cpp std::ostream& operator<<(std::ostream& o, const basic_json& j)` replaces function + `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` which has been deprecated in version 3.0.0. + It will be removed in version 4.0.0. Please replace calls like `#!cpp j >> o;` with `#!cpp o << j;`. + +## Examples + +??? example "Example: (1) serialize JSON value to stream" + + The example below shows the serialization with different parameters to `width` to adjust the indentation level. + + ```cpp + --8<-- "examples/operator_ltlt__basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_ltlt__basic_json.output" + ``` + +??? example "Example: (2) write JSON pointer to stream" + + The example below shows how to write a JSON pointer to a stream. + + ```cpp + --8<-- "examples/operator_ltlt__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_ltlt__json_pointer.output" + ``` +## Version history + +1. Added in version 1.0.0. Added support for indentation character and deprecated + `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` in version 3.0.0. +3. Added in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/api/ordered_json.md b/json-develop/docs/mkdocs/docs/api/ordered_json.md new file mode 100644 index 0000000..7cfd9f4 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/ordered_json.md @@ -0,0 +1,32 @@ +# nlohmann::ordered_json + +```cpp +using ordered_json = basic_json; +``` + +This type preserves the insertion order of object keys. + +## Examples + +??? example + + The example below demonstrates how `ordered_json` preserves the insertion order of object keys. + + ```cpp + --8<-- "examples/ordered_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_json.output" + ``` + +## See also + +- [ordered_map](ordered_map.md) +- [Object Order](../features/object_order.md) + +## Version history + +Since version 3.9.0. diff --git a/json-develop/docs/mkdocs/docs/api/ordered_map.md b/json-develop/docs/mkdocs/docs/api/ordered_map.md new file mode 100644 index 0000000..160b85c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/api/ordered_map.md @@ -0,0 +1,77 @@ +# nlohmann::ordered_map + +```cpp +template, + class Allocator = std::allocator>> +struct ordered_map : std::vector, Allocator>; +``` + +A minimal map-like container that preserves insertion order for use within [`nlohmann::ordered_json`](ordered_json.md) +(`nlohmann::basic_json`). + +## Template parameters + +`Key` +: key type + +`T` +: mapped type + +`IgnoredLess` +: comparison function (ignored and only added to ensure compatibility with `#!cpp std::map`) + +`Allocator` +: allocator type + +## Member types + +- **key_type** - key type (`Key`) +- **mapped_type** - mapped type (`T`) +- **Container** - base container type (`#!cpp std::vector, Allocator>`) +- **iterator** +- **const_iterator** +- **size_type** +- **value_type** +- **key_compare** - key comparison function +```cpp +std::equal_to // until C++14 + +std::equal_to<> // since C++14 +``` + +## Member functions + +- (constructor) +- (destructor) +- **emplace** +- **operator\[\]** +- **at** +- **erase** +- **count** +- **find** +- **insert** + +## Examples + +??? example + + The example shows the different behavior of `std::map` and `nlohmann::ordered_map`. + + ```cpp + --8<-- "examples/ordered_map.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_map.output" + ``` + +## See also + +- [ordered_json](ordered_json.md) + +## Version history + +- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](ordered_json.md). +- Added **key_compare** member in version 3.11.0. diff --git a/json-develop/docs/mkdocs/docs/css/custom.css b/json-develop/docs/mkdocs/docs/css/custom.css new file mode 100644 index 0000000..7a1008b --- /dev/null +++ b/json-develop/docs/mkdocs/docs/css/custom.css @@ -0,0 +1,4 @@ +/* disable ligatures in code and preformatted blocks */ +code, pre { + font-variant-ligatures: none; +} diff --git a/json-develop/docs/mkdocs/docs/features/arbitrary_types.md b/json-develop/docs/mkdocs/docs/features/arbitrary_types.md new file mode 100644 index 0000000..046a597 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/arbitrary_types.md @@ -0,0 +1,274 @@ +# Arbitrary Type Conversions + +Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines: + +```cpp +namespace ns { + // a simple struct to model a person + struct person { + std::string name; + std::string address; + int age; + }; +} // namespace ns + +ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// convert to JSON: copy each value into the JSON object +json j; +j["name"] = p.name; +j["address"] = p.address; +j["age"] = p.age; + +// ... + +// convert from JSON: copy each value from the JSON object +ns::person p { + j["name"].get(), + j["address"].get(), + j["age"].get() +}; +``` + +It works, but that's quite a lot of boilerplate... Fortunately, there's a better way: + +```cpp +// create a person +ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// conversion: person -> json +json j = p; + +std::cout << j << std::endl; +// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} + +// conversion: json -> person +auto p2 = j.get(); + +// that's it +assert(p == p2); +``` + +## Basic usage + +To make this work with one of your types, you only need to provide two functions: + +```cpp +using json = nlohmann::json; + +namespace ns { + void to_json(json& j, const person& p) { + j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} }; + } + + void from_json(const json& j, person& p) { + j.at("name").get_to(p.name); + j.at("address").get_to(p.address); + j.at("age").get_to(p.age); + } +} // namespace ns +``` + +That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. +Likewise, when calling `get()` or `get_to(your_type&)`, the `from_json` method will be called. + +Some important things: + +* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined). +* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise. +* When using `get()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.) +* In function `from_json`, use function [`at()`](../api/basic_json/at.md) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. +* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. + + +## Simplify your life with macros + +If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate. + +There are four macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object: + +- [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_non_intrusive.md) is to be defined inside the namespace of the class/struct to create code for. It will throw an exception in `from_json()` due to a missing value in the JSON object. +- [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_non_intrusive.md) is to be defined inside the namespace of the class/struct to create code for. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type. +- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_intrusive.md) is to be defined inside the class/struct to create code for. This macro can also access private members. It will throw an exception in `from_json()` due to a missing value in the JSON object. +- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_intrusive.md) is to be defined inside the class/struct to create code for. This macro can also access private members. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type. + +In all macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. You can read more docs about them starting from [here](macros.md#nlohmann_define_type_intrusivetype-member). + +!!! info "Implementation limits" + + - The current macro implementations are limited to at most 64 member variables. If you want to serialize/deserialize + types with more than 64 member variables, you need to define the `to_json`/`from_json` functions manually. + - The macros only work for the [`nlohmann::json`](../api/json.md) type; other specializations such as + [`nlohmann::ordered_json`](../api/ordered_json.md) are currently unsupported. + +??? example + + The `to_json`/`from_json` functions for the `person` struct above can be created with: + + ```cpp + namespace ns { + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age) + } + ``` + + Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed: + + ```cpp + namespace ns { + class address { + private: + std::string street; + int housenumber; + int postcode; + + public: + NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode) + }; + } + ``` + +## How do I convert third-party types? + +This requires a bit more advanced technique. But first, let's see how this conversion mechanism works: + +The library uses **JSON Serializers** to convert types to json. +The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)). + +It is implemented like this (simplified): + +```cpp +template +struct adl_serializer { + static void to_json(json& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + static void from_json(const json& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`... + +To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example: + +```cpp +// partial specialization (full specialization works too) +NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> { + static void to_json(json& j, const boost::optional& opt) { + if (opt == boost::none) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, boost::optional& opt) { + if (j.is_null()) { + opt = boost::none; + } else { + opt = j.get(); // same as above, but with + // adl_serializer::from_json + } + } +}; +NLOHMANN_JSON_NAMESPACE_END +``` + +!!! note "ABI compatibility" + + Use [`NLOHMANN_JSON_NAMESPACE_BEGIN`](../api/macros/nlohmann_json_namespace_begin.md) and `NLOHMANN_JSON_NAMESPACE_END` + instead of `#!cpp namespace nlohmann { }` in code which may be linked with different versions of this library. + +## How can I use `get()` for non-default constructible/non-copyable types? + +There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload: + +```cpp +struct move_only_type { + move_only_type() = delete; + move_only_type(int ii): i(ii) {} + move_only_type(const move_only_type&) = delete; + move_only_type(move_only_type&&) = default; + + int i; +}; + +namespace nlohmann { + template <> + struct adl_serializer { + // note: the return type is no longer 'void', and the method only takes + // one argument + static move_only_type from_json(const json& j) { + return {j.get()}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert move_only_type to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, move_only_type t) { + j = t.i; + } + }; +} +``` + +## Can I write my own serializer? (Advanced use) + +Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-udt.cpp) in the test suite, to see a few examples. + +If you write your own serializer, you'll need to do a few things: + +- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`) +- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods +- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL + +Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL. + +```cpp +// You should use void as a second template argument +// if you don't need compile-time checks on T +template::type> +struct less_than_32_serializer { + template + static void to_json(BasicJsonType& j, T value) { + // we want to use ADL, and call the correct to_json overload + using nlohmann::to_json; // this method is called by adl_serializer, + // this is where the magic happens + to_json(j, value); + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing here + using nlohmann::from_json; + from_json(j, value); + } +}; +``` + +Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention: + +```cpp +template +struct bad_serializer +{ + template + static void to_json(BasicJsonType& j, const T& value) { + // this calls BasicJsonType::json_serializer::to_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + j = value; + } + + template + static void to_json(const BasicJsonType& j, T& value) { + // this calls BasicJsonType::json_serializer::from_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + value = j.template get(); // oops! + } +}; +``` diff --git a/json-develop/docs/mkdocs/docs/features/assertions.md b/json-develop/docs/mkdocs/docs/features/assertions.md new file mode 100644 index 0000000..2bad62e --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/assertions.md @@ -0,0 +1,131 @@ +# Runtime Assertions + +The code contains numerous debug assertions to ensure class invariants are valid or to detect undefined behavior. +Whereas the former class invariants are nothing to be concerned of, the latter checks for undefined behavior are to +detect bugs in client code. + +## Switch off runtime assertions + +Runtime assertions can be switched off by defining the preprocessor macro `NDEBUG` (see the +[documentation of assert](https://en.cppreference.com/w/cpp/error/assert)) which is the default for release builds. + +## Change assertion behavior + +The behavior of runtime assertions can be changes by defining macro [`JSON_ASSERT(x)`](../api/macros/json_assert.md) +before including the `json.hpp` header. + +## Function with runtime assertions + +### Unchecked object access to a const value + +Function [`operator[]`](../api/basic_json/operator%5B%5D.md) implements unchecked access for objects. Whereas a missing +key is added in case of non-const objects, accessing a const object with a missing key is undefined behavior (think of a +dereferenced null pointer) and yields a runtime assertion. + +If you are not sure whether an element in an object exists, use checked access with the +[`at` function](../api/basic_json/at.md) or call the [`contains` function](../api/basic_json/contains.md) before. + +See also the documentation on [element access](element_access/index.md). + +??? example "Example 1: Missing object key" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + const json j = {{"key", "value"}}; + auto v = j["missing"]; + } + ``` + + Output: + + ``` + Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144. + ``` + +### Constructing from an uninitialized iterator range + +Constructing a JSON value from an iterator range (see [constructor](../api/basic_json/basic_json.md)) with an +uninitialized iterator is undefined behavior and yields a runtime assertion. + +??? example "Example 2: Uninitialized iterator range" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + json::iterator it1, it2; + json j(it1, it2); + } + ``` + + Output: + + ``` + Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368. + ``` + +### Operations on uninitialized iterators + +Any operation on uninitialized iterators (i.e., iterators that are not associated with any JSON value) is undefined +behavior and yields a runtime assertion. + +??? example "Example 3: Uninitialized iterator" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + json::iterator it; + ++it; + } + ``` + + Output: + + ``` + Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368. + ``` + +### Reading from a null `FILE` pointer + +Reading from a null `#!cpp FILE` pointer is undefined behavior and yields a runtime assertion. This can happen when +calling `#!cpp std::fopen` on a nonexistent file. + +??? example "Example 4: Uninitialized iterator" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + std::FILE* f = std::fopen("nonexistent_file.json", "r"); + json j = json::parse(f); + } + ``` + + Output: + + ``` + Assertion failed: (m_file != nullptr), function file_input_adapter, file input_adapters.hpp, line 55. + ``` diff --git a/json-develop/docs/mkdocs/docs/features/binary_formats/bjdata.md b/json-develop/docs/mkdocs/docs/features/binary_formats/bjdata.md new file mode 100644 index 0000000..a89a228 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_formats/bjdata.md @@ -0,0 +1,194 @@ +# BJData + +The [BJData format](https://neurojson.org) was derived from and improved upon +[Universal Binary JSON(UBJSON)](https://ubjson.org) specification (Draft 12). Specifically, it introduces an optimized +array container for efficient storage of N-dimensional packed arrays (**ND-arrays**); it also adds 4 new type markers - +`[u] - uint16`, `[m] - uint32`, `[M] - uint64` and `[h] - float16` - to unambiguously map common binary numeric types; +furthermore, it uses little-endian (LE) to store all numerics instead of big-endian (BE) as in UBJSON to avoid +unnecessary conversions on commonly available platforms. + +Compared to other binary JSON-like formats such as MessagePack and CBOR, both BJData and UBJSON demonstrate a rare +combination of being both binary and **quasi-human-readable**. This is because all semantic elements in BJData and +UBJSON, including the data-type markers and name/string types are directly human-readable. Data stored in the +BJData/UBJSON format are not only compact in size, fast to read/write, but also can be directly searched or read using +simple processing. + +!!! abstract "References" + + - [BJData Specification](https://neurojson.org/bjdata/draft2) + +## Serialization + +The library uses the following mapping from JSON values types to BJData types according to the BJData specification: + +| JSON value type | value/range | BJData type | marker | +|-----------------|-------------------------------------------|----------------|--------| +| null | `null` | null | `Z` | +| boolean | `true` | true | `T` | +| boolean | `false` | false | `F` | +| number_integer | -9223372036854775808..-2147483649 | int64 | `L` | +| number_integer | -2147483648..-32769 | int32 | `l` | +| number_integer | -32768..-129 | int16 | `I` | +| number_integer | -128..127 | int8 | `i` | +| number_integer | 128..255 | uint8 | `U` | +| number_integer | 256..32767 | int16 | `I` | +| number_integer | 32768..65535 | uint16 | `u` | +| number_integer | 65536..2147483647 | int32 | `l` | +| number_integer | 2147483648..4294967295 | uint32 | `m` | +| number_integer | 4294967296..9223372036854775807 | int64 | `L` | +| number_integer | 9223372036854775808..18446744073709551615 | uint64 | `M` | +| number_unsigned | 0..127 | int8 | `i` | +| number_unsigned | 128..255 | uint8 | `U` | +| number_unsigned | 256..32767 | int16 | `I` | +| number_unsigned | 32768..65535 | uint16 | `u` | +| number_unsigned | 65536..2147483647 | int32 | `l` | +| number_unsigned | 2147483648..4294967295 | uint32 | `m` | +| number_unsigned | 4294967296..9223372036854775807 | int64 | `L` | +| number_unsigned | 9223372036854775808..18446744073709551615 | uint64 | `M` | +| number_float | *any value* | float64 | `D` | +| string | *with shortest length indicator* | string | `S` | +| array | *see notes on optimized format/ND-array* | array | `[` | +| object | *see notes on optimized format* | map | `{` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a BJData value. + + Any BJData output created by `to_bjdata` can be successfully parsed by `from_bjdata`. + +!!! warning "Size constraints" + + The following values can **not** be converted to a BJData value: + + - strings with more than 18446744073709551615 bytes, i.e., $2^{64}-1$ bytes (theoretical) + +!!! info "Unused BJData markers" + + The following markers are not used in the conversion: + + - `Z`: no-op values are not created. + - `C`: single-byte strings are serialized with `S` markers. + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the + `dump()` function which serializes NaN or Infinity to `#!json null`. + +!!! info "Endianness" + + A breaking difference between BJData and UBJSON is the endianness of numerical values. In BJData, all numerical data + types (integers `UiuImlML` and floating-point values `hdD`) are stored in the little-endian (LE) byte order as + opposed to big-endian as used by UBJSON. Adopting LE to store numeric records avoids unnecessary byte swapping on + most modern computers where LE is used as the default byte order. + +!!! info "Optimized formats" + + Optimized formats for containers are supported via two parameters of + [`to_bjdata`](../../api/basic_json/to_bjdata.md): + + - Parameter `use_size` adds size information to the beginning of a container and removes the closing marker. + - Parameter `use_type` further checks whether all elements of a container have the same type and adds the type + marker to the beginning of the container. The `use_type` parameter must only be used together with + `use_size = true`. + + Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the + receiving side is immediately informed of the number of elements in the container. + +!!! info "ND-array optimized format" + + BJData extends UBJSON's optimized array **size** marker to support ND-arrays of uniform numerical data types + (referred to as *packed arrays*). For example, the 2-D `uint8` integer array `[[1,2],[3,4],[5,6]]`, stored as nested + optimized array in UBJSON `[ [$U#i2 1 2 [$U#i2 3 4 [$U#i2 5 6 ]`, can be further compressed in BJData to + `[$U#[$i#i2 2 3 1 2 3 4 5 6` or `[$U#[i2 i3] 1 2 3 4 5 6`. + + To maintain type and size information, ND-arrays are converted to JSON objects following the **annotated array + format** (defined in the [JData specification (Draft 3)][JDataAAFmt]), when parsed using + [`from_bjdata`](../../api/basic_json/from_bjdata.md). For example, the above 2-D `uint8` array can be parsed and + accessed as + + ```json + { + "_ArrayType_": "uint8", + "_ArraySize_": [2,3], + "_ArrayData_": [1,2,3,4,5,6] + } + ``` + + Likewise, when a JSON object in the above form is serialzed using + [`to_bjdata`](../../api/basic_json/to_bjdata.md), it is automatically converted into a compact BJData ND-array. The + only exception is, that when the 1-dimensional vector stored in `"_ArraySize_"` contains a single integer or two + integers with one being 1, a regular 1-D optimized array is generated. + + The current version of this library does not yet support automatic detection of and conversion from a nested JSON + array input to a BJData ND-array. + + [JDataAAFmt]: https://github.com/NeuroJSON/jdata/blob/master/JData_specification.md#annotated-storage-of-n-d-arrays) + +!!! info "Restrictions in optimized data types for arrays and objects" + + Due to diminished space saving, hampered readability, and increased security risks, in BJData, the allowed data + types following the `$` marker in an optimized array and object container are restricted to + **non-zero-fixed-length** data types. Therefore, the valid optimized type markers can only be one of `UiuImlMLhdDC`. + This also means other variable (`[{SH`) or zero-length types (`TFN`) can not be used in an optimized array or object + in BJData. + +!!! info "Binary values" + + If the JSON data contains the binary type, the value stored is a list of integers, as suggested by the BJData + documentation. In particular, this means that the serialization and the deserialization of JSON containing binary + values into BJData and back will result in a different JSON object. + +??? example + + ```cpp + --8<-- "examples/to_bjdata.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_bjdata.output" + ``` + +## Deserialization + +The library maps BJData types to JSON value types as follows: + +| BJData type | JSON value type | marker | +|-------------|-----------------------------------------|--------| +| no-op | *no value, next value is read* | `N` | +| null | `null` | `Z` | +| false | `false` | `F` | +| true | `true` | `T` | +| float16 | number_float | `h` | +| float32 | number_float | `d` | +| float64 | number_float | `D` | +| uint8 | number_unsigned | `U` | +| int8 | number_integer | `i` | +| uint16 | number_unsigned | `u` | +| int16 | number_integer | `I` | +| uint32 | number_unsigned | `m` | +| int32 | number_integer | `l` | +| uint64 | number_unsigned | `M` | +| int64 | number_integer | `L` | +| string | string | `S` | +| char | string | `C` | +| array | array (optimized values are supported) | `[` | +| ND-array | object (in JData annotated array format)|`[$.#[.`| +| object | object (optimized values are supported) | `{` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any BJData value can be converted to a JSON value. + +??? example + + ```cpp + --8<-- "examples/from_bjdata.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bjdata.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/binary_formats/bson.md b/json-develop/docs/mkdocs/docs/features/binary_formats/bson.md new file mode 100644 index 0000000..f3b8cf1 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_formats/bson.md @@ -0,0 +1,96 @@ +# BSON + +BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the +embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow +representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type. + +!!! abstract "References" + + - [BSON Website](http://bsonspec.org) - the main source on BSON + - [BSON Specification](http://bsonspec.org/spec.html) - the specification + + +## Serialization + +The library uses the following mapping from JSON values types to BSON types: + +| JSON value type | value/range | BSON type | marker | +|-----------------|-------------------------------------------|-----------|--------| +| null | `null` | null | 0x0A | +| boolean | `true`, `false` | boolean | 0x08 | +| number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 | +| number_integer | -2147483648..2147483647 | int32 | 0x10 | +| number_integer | 2147483648..9223372036854775807 | int64 | 0x12 | +| number_unsigned | 0..2147483647 | int32 | 0x10 | +| number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 | +| number_unsigned | 9223372036854775808..18446744073709551615 | -- | -- | +| number_float | *any value* | double | 0x01 | +| string | *any value* | string | 0x02 | +| array | *any value* | document | 0x04 | +| object | *any value* | document | 0x03 | +| binary | *any value* | binary | 0x05 | + +!!! warning "Incomplete mapping" + + The mapping is **incomplete**, since only JSON-objects (and things + contained therein) can be serialized to BSON. + Also, integers larger than 9223372036854775807 cannot be serialized to BSON, + and the keys may not contain U+0000, since they are serialized a + zero-terminated c-strings. + +??? example + + ```cpp + --8<-- "examples/to_bson.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_bson.output" + ``` + + +## Deserialization + +The library maps BSON record types to JSON value types as follows: + +| BSON type | BSON marker byte | JSON value type | +|-----------------------|------------------|-----------------| +| double | 0x01 | number_float | +| string | 0x02 | string | +| document | 0x03 | object | +| array | 0x04 | array | +| binary | 0x05 | binary | +| undefined | 0x06 | *unsupported* | +| ObjectId | 0x07 | *unsupported* | +| boolean | 0x08 | boolean | +| UTC Date-Time | 0x09 | *unsupported* | +| null | 0x0A | null | +| Regular Expr. | 0x0B | *unsupported* | +| DB Pointer | 0x0C | *unsupported* | +| JavaScript Code | 0x0D | *unsupported* | +| Symbol | 0x0E | *unsupported* | +| JavaScript Code | 0x0F | *unsupported* | +| int32 | 0x10 | number_integer | +| Timestamp | 0x11 | *unsupported* | +| 128-bit decimal float | 0x13 | *unsupported* | +| Max Key | 0x7F | *unsupported* | +| Min Key | 0xFF | *unsupported* | + +!!! warning "Incomplete mapping" + + The mapping is **incomplete**. The unsupported mappings are indicated in the table above. + + +??? example + + ```cpp + --8<-- "examples/from_bson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bson.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/binary_formats/cbor.md b/json-develop/docs/mkdocs/docs/features/binary_formats/cbor.md new file mode 100644 index 0000000..2d0a1da --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_formats/cbor.md @@ -0,0 +1,181 @@ +# CBOR + +The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely +small code size, fairly small message size, and extensibility without the need for version negotiation. + +!!! abstract "References" + + - [CBOR Website](http://cbor.io) - the main source on CBOR + - [CBOR Playground](http://cbor.me) - an interactive webpage to translate between JSON and CBOR + - [RFC 7049](https://tools.ietf.org/html/rfc7049) - the CBOR specification + +## Serialization + +The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification +([RFC 7049](https://www.rfc-editor.org/rfc/rfc7049.html)): + +| JSON value type | value/range | CBOR type | first byte | +|-----------------|--------------------------------------------|-----------------------------------|------------| +| null | `null` | Null | 0xF6 | +| boolean | `true` | True | 0xF5 | +| boolean | `false` | False | 0xF4 | +| number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B | +| number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A | +| number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 | +| number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 | +| number_integer | -24..-1 | Negative integer | 0x20..0x37 | +| number_integer | 0..23 | Integer | 0x00..0x17 | +| number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 | +| number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 | +| number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A | +| number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B | +| number_unsigned | 0..23 | Integer | 0x00..0x17 | +| number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 | +| number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 | +| number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A | +| number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B | +| number_float | *any value representable by a float* | Single-Precision Float | 0xFA | +| number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB | +| string | *length*: 0..23 | UTF-8 string | 0x60..0x77 | +| string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78 | +| string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 | +| string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A | +| string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B | +| array | *size*: 0..23 | array | 0x80..0x97 | +| array | *size*: 23..255 | array (1 byte follow) | 0x98 | +| array | *size*: 256..65535 | array (2 bytes follow) | 0x99 | +| array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A | +| array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B | +| object | *size*: 0..23 | map | 0xA0..0xB7 | +| object | *size*: 23..255 | map (1 byte follow) | 0xB8 | +| object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 | +| object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA | +| object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB | +| binary | *size*: 0..23 | byte string | 0x40..0x57 | +| binary | *size*: 23..255 | byte string (1 byte follow) | 0x58 | +| binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59 | +| binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A | +| binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B | + +Binary values with subtype are mapped to tagged values (0xD8..0xDB) depending on the subtype, followed by a byte string, +see "binary" cells in the table above. + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value. + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to `null`. + +!!! info "Unused CBOR types" + + The following CBOR types are not used in the conversion: + + - UTF-8 strings terminated by "break" (0x7F) + - arrays terminated by "break" (0x9F) + - maps terminated by "break" (0xBF) + - byte strings terminated by "break" (0x5F) + - date/time (0xC0..0xC1) + - bignum (0xC2..0xC3) + - decimal fraction (0xC4) + - bigfloat (0xC5) + - expected conversions (0xD5..0xD7) + - simple values (0xE0..0xF3, 0xF8) + - undefined (0xF7) + - half-precision floats (0xF9) + - break (0xFF) + +!!! info "Tagged items" + + Binary subtypes will be serialized as tagged items. See [binary values](../binary_values.md#cbor) for an example. + +??? example + + ```cpp + --8<-- "examples/to_cbor.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_cbor.output" + ``` + +## Deserialization + +The library maps CBOR types to JSON value types as follows: + +| CBOR type | JSON value type | first byte | +|------------------------|-----------------|------------| +| Integer | number_unsigned | 0x00..0x17 | +| Unsigned integer | number_unsigned | 0x18 | +| Unsigned integer | number_unsigned | 0x19 | +| Unsigned integer | number_unsigned | 0x1A | +| Unsigned integer | number_unsigned | 0x1B | +| Negative integer | number_integer | 0x20..0x37 | +| Negative integer | number_integer | 0x38 | +| Negative integer | number_integer | 0x39 | +| Negative integer | number_integer | 0x3A | +| Negative integer | number_integer | 0x3B | +| Byte string | binary | 0x40..0x57 | +| Byte string | binary | 0x58 | +| Byte string | binary | 0x59 | +| Byte string | binary | 0x5A | +| Byte string | binary | 0x5B | +| UTF-8 string | string | 0x60..0x77 | +| UTF-8 string | string | 0x78 | +| UTF-8 string | string | 0x79 | +| UTF-8 string | string | 0x7A | +| UTF-8 string | string | 0x7B | +| UTF-8 string | string | 0x7F | +| array | array | 0x80..0x97 | +| array | array | 0x98 | +| array | array | 0x99 | +| array | array | 0x9A | +| array | array | 0x9B | +| array | array | 0x9F | +| map | object | 0xA0..0xB7 | +| map | object | 0xB8 | +| map | object | 0xB9 | +| map | object | 0xBA | +| map | object | 0xBB | +| map | object | 0xBF | +| False | `false` | 0xF4 | +| True | `true` | 0xF5 | +| Null | `null` | 0xF6 | +| Half-Precision Float | number_float | 0xF9 | +| Single-Precision Float | number_float | 0xFA | +| Double-Precision Float | number_float | 0xFB | + +!!! warning "Incomplete mapping" + + The mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors: + + - date/time (0xC0..0xC1) + - bignum (0xC2..0xC3) + - decimal fraction (0xC4) + - bigfloat (0xC5) + - expected conversions (0xD5..0xD7) + - simple values (0xE0..0xF3, 0xF8) + - undefined (0xF7) + +!!! warning "Object keys" + + CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected. + +!!! warning "Tagged items" + + Tagged items will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`. They can be stored by passing `cbor_tag_handler_t::store` to function `from_cbor`. + +??? example + + ```cpp + --8<-- "examples/from_cbor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_cbor.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/binary_formats/index.md b/json-develop/docs/mkdocs/docs/features/binary_formats/index.md new file mode 100644 index 0000000..e74290b --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_formats/index.md @@ -0,0 +1,52 @@ +# Binary Formats + +Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over +a network. Hence, the library supports + +- [BJData](bjdata.md) (Binary JData), +- [BSON](bson.md) (Binary JSON), +- [CBOR](cbor.md) (Concise Binary Object Representation), +- [MessagePack](messagepack.md), and +- [UBJSON](ubjson.md) (Universal Binary JSON) + +to efficiently encode JSON values to byte vectors and to decode such vectors. + +## Comparison + +### Completeness + +| Format | Serialization | Deserialization | +|-------------|-----------------------------------------------|----------------------------------------------| +| BJData | complete | complete | +| BSON | incomplete: top-level value must be an object | incomplete, but all JSON types are supported | +| CBOR | complete | incomplete, but all JSON types are supported | +| MessagePack | complete | complete | +| UBJSON | complete | complete | + +### Binary values + +| Format | Binary values | Binary subtypes | +|-------------|---------------|-----------------| +| BJData | not supported | not supported | +| BSON | supported | supported | +| CBOR | supported | supported | +| MessagePack | supported | supported | +| UBJSON | not supported | not supported | + +See [binary values](../binary_values.md) for more information. + +### Sizes + +| Format | canada.json | twitter.json | citm_catalog.json | jeopardy.json | +|--------------------|-------------|--------------|-------------------|---------------| +| BJData | 53.2 % | 91.1 % | 78.1 % | 96.6 % | +| BJData (size) | 58.6 % | 92.1 % | 86.7 % | 97.4 % | +| BJData (size+tyoe) | 58.6 % | 92.1 % | 86.5 % | 97.4 % | +| BSON | 85.8 % | 95.2 % | 95.8 % | 106.7 % | +| CBOR | 50.5 % | 86.3 % | 68.4 % | 88.0 % | +| MessagePack | 50.5 % | 86.0 % | 68.5 % | 87.9 % | +| UBJSON | 53.2 % | 91.3 % | 78.2 % | 96.6 % | +| UBJSON (size) | 58.6 % | 92.3 % | 86.8 % | 97.4 % | +| UBJSON (size+type) | 55.9 % | 92.3 % | 85.0 % | 95.0 % | + +Sizes compared to minified JSON value. diff --git a/json-develop/docs/mkdocs/docs/features/binary_formats/messagepack.md b/json-develop/docs/mkdocs/docs/features/binary_formats/messagepack.md new file mode 100644 index 0000000..b2f69f1 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_formats/messagepack.md @@ -0,0 +1,143 @@ +# MessagePack + +MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. +But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one +extra byte in addition to the strings themselves. + +!!! abstract "References" + + - [MessagePack website](https://msgpack.org) + - [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md) + +## Serialization + +The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack +specification: + +| JSON value type | value/range | MessagePack type | first byte | +|-----------------|------------------------------------------|------------------|------------| +| null | `null` | nil | 0xC0 | +| boolean | `true` | true | 0xC3 | +| boolean | `false` | false | 0xC2 | +| number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 | +| number_integer | -2147483648..-32769 | int32 | 0xD2 | +| number_integer | -32768..-129 | int16 | 0xD1 | +| number_integer | -128..-33 | int8 | 0xD0 | +| number_integer | -32..-1 | negative fixint | 0xE0..0xFF | +| number_integer | 0..127 | positive fixint | 0x00..0x7F | +| number_integer | 128..255 | uint 8 | 0xCC | +| number_integer | 256..65535 | uint 16 | 0xCD | +| number_integer | 65536..4294967295 | uint 32 | 0xCE | +| number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF | +| number_unsigned | 0..127 | positive fixint | 0x00..0x7F | +| number_unsigned | 128..255 | uint 8 | 0xCC | +| number_unsigned | 256..65535 | uint 16 | 0xCD | +| number_unsigned | 65536..4294967295 | uint 32 | 0xCE | +| number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF | +| number_float | *any value representable by a float* | float 32 | 0xCA | +| number_float | *any value NOT representable by a float* | float 64 | 0xCB | +| string | *length*: 0..31 | fixstr | 0xA0..0xBF | +| string | *length*: 32..255 | str 8 | 0xD9 | +| string | *length*: 256..65535 | str 16 | 0xDA | +| string | *length*: 65536..4294967295 | str 32 | 0xDB | +| array | *size*: 0..15 | fixarray | 0x90..0x9F | +| array | *size*: 16..65535 | array 16 | 0xDC | +| array | *size*: 65536..4294967295 | array 32 | 0xDD | +| object | *size*: 0..15 | fix map | 0x80..0x8F | +| object | *size*: 16..65535 | map 16 | 0xDE | +| object | *size*: 65536..4294967295 | map 32 | 0xDF | +| binary | *size*: 0..255 | bin 8 | 0xC4 | +| binary | *size*: 256..65535 | bin 16 | 0xC5 | +| binary | *size*: 65536..4294967295 | bin 32 | 0xC6 | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a MessagePack value. + + Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. + +!!! warning "Size constraints" + + The following values can **not** be converted to a MessagePack value: + + - strings with more than 4294967295 bytes + - byte strings with more than 4294967295 bytes + - arrays with more than 4294967295 elements + - objects with more than 4294967295 elements + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly in contrast to the + [dump](../../api/basic_json/dump.md) function which serializes NaN or Infinity to `null`. + +??? example + + ```cpp + --8<-- "examples/to_msgpack.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_msgpack.output" + ``` + +## Deserialization + +The library maps MessagePack types to JSON value types as follows: + +| MessagePack type | JSON value type | first byte | +|------------------|-----------------|------------| +| positive fixint | number_unsigned | 0x00..0x7F | +| fixmap | object | 0x80..0x8F | +| fixarray | array | 0x90..0x9F | +| fixstr | string | 0xA0..0xBF | +| nil | `null` | 0xC0 | +| false | `false` | 0xC2 | +| true | `true` | 0xC3 | +| float 32 | number_float | 0xCA | +| float 64 | number_float | 0xCB | +| uint 8 | number_unsigned | 0xCC | +| uint 16 | number_unsigned | 0xCD | +| uint 32 | number_unsigned | 0xCE | +| uint 64 | number_unsigned | 0xCF | +| int 8 | number_integer | 0xD0 | +| int 16 | number_integer | 0xD1 | +| int 32 | number_integer | 0xD2 | +| int 64 | number_integer | 0xD3 | +| str 8 | string | 0xD9 | +| str 16 | string | 0xDA | +| str 32 | string | 0xDB | +| array 16 | array | 0xDC | +| array 32 | array | 0xDD | +| map 16 | object | 0xDE | +| map 32 | object | 0xDF | +| bin 8 | binary | 0xC4 | +| bin 16 | binary | 0xC5 | +| bin 32 | binary | 0xC6 | +| ext 8 | binary | 0xC7 | +| ext 16 | binary | 0xC8 | +| ext 32 | binary | 0xC9 | +| fixext 1 | binary | 0xD4 | +| fixext 2 | binary | 0xD5 | +| fixext 4 | binary | 0xD6 | +| fixext 8 | binary | 0xD7 | +| fixext 16 | binary | 0xD8 | +| negative fixint | number_integer | 0xE0-0xFF | + +!!! info + + Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. + + +??? example + + ```cpp + --8<-- "examples/from_msgpack.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_msgpack.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/binary_formats/ubjson.md b/json-develop/docs/mkdocs/docs/features/binary_formats/ubjson.md new file mode 100644 index 0000000..76956d6 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_formats/ubjson.md @@ -0,0 +1,126 @@ +# UBJSON + +Universal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to +achieve the generality of JSON, combined with being much easier to process than JSON. + +!!! abstract "References" + + - [UBJSON Website](http://ubjson.org) + +## Serialization + +The library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification: + +| JSON value type | value/range | UBJSON type | marker | +|-----------------|-----------------------------------|----------------|--------| +| null | `null` | null | `Z` | +| boolean | `true` | true | `T` | +| boolean | `false` | false | `F` | +| number_integer | -9223372036854775808..-2147483649 | int64 | `L` | +| number_integer | -2147483648..-32769 | int32 | `l` | +| number_integer | -32768..-129 | int16 | `I` | +| number_integer | -128..127 | int8 | `i` | +| number_integer | 128..255 | uint8 | `U` | +| number_integer | 256..32767 | int16 | `I` | +| number_integer | 32768..2147483647 | int32 | `l` | +| number_integer | 2147483648..9223372036854775807 | int64 | `L` | +| number_unsigned | 0..127 | int8 | `i` | +| number_unsigned | 128..255 | uint8 | `U` | +| number_unsigned | 256..32767 | int16 | `I` | +| number_unsigned | 32768..2147483647 | int32 | `l` | +| number_unsigned | 2147483648..9223372036854775807 | int64 | `L` | +| number_unsigned | 2147483649..18446744073709551615 | high-precision | `H` | +| number_float | *any value* | float64 | `D` | +| string | *with shortest length indicator* | string | `S` | +| array | *see notes on optimized format* | array | `[` | +| object | *see notes on optimized format* | map | `{` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a UBJSON value. + + Any UBJSON output created by `to_ubjson` can be successfully parsed by `from_ubjson`. + +!!! warning "Size constraints" + + The following values can **not** be converted to a UBJSON value: + + - strings with more than 9223372036854775807 bytes (theoretical) + +!!! info "Unused UBJSON markers" + + The following markers are not used in the conversion: + + - `Z`: no-op values are not created. + - `C`: single-byte strings are serialized with `S` markers. + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the + `dump()` function which serializes NaN or Infinity to `null`. + +!!! info "Optimized formats" + + The optimized formats for containers are supported: Parameter `use_size` adds size information to the beginning of a + container and removes the closing marker. Parameter `use_type` further checks whether all elements of a container + have the same type and adds the type marker to the beginning of the container. The `use_type` parameter must only be + used together with `use_size = true`. + + Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the + receiving side is immediately informed on the number of elements of the container. + +!!! info "Binary values" + + If the JSON data contains the binary type, the value stored is a list of integers, as suggested by the UBJSON + documentation. In particular, this means that serialization and the deserialization of a JSON containing binary + values into UBJSON and back will result in a different JSON object. + +??? example + + ```cpp + --8<-- "examples/to_ubjson.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_ubjson.output" + ``` + +## Deserialization + +The library maps UBJSON types to JSON value types as follows: + +| UBJSON type | JSON value type | marker | +|-------------|-----------------------------------------|--------| +| no-op | *no value, next value is read* | `N` | +| null | `null` | `Z` | +| false | `false` | `F` | +| true | `true` | `T` | +| float32 | number_float | `d` | +| float64 | number_float | `D` | +| uint8 | number_unsigned | `U` | +| int8 | number_integer | `i` | +| int16 | number_integer | `I` | +| int32 | number_integer | `l` | +| int64 | number_integer | `L` | +| string | string | `S` | +| char | string | `C` | +| array | array (optimized values are supported) | `[` | +| object | object (optimized values are supported) | `{` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any UBJSON value can be converted to a JSON value. + +??? example + + ```cpp + --8<-- "examples/from_ubjson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_ubjson.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/binary_values.md b/json-develop/docs/mkdocs/docs/features/binary_values.md new file mode 100644 index 0000000..5ad6433 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/binary_values.md @@ -0,0 +1,372 @@ +# Binary Values + +The library implements several [binary formats](binary_formats/index.md) that encode JSON in an efficient way. Most of +these formats support binary values; that is, values that have semantics define outside the library and only define a +sequence of bytes to be stored. + +JSON itself does not have a binary value. As such, binary values are an extension that this library implements to store +values received by a binary format. Binary values are never created by the JSON parser, and are only part of a +serialized JSON text if they have been created manually or via a binary format. + +## API for binary values + +```plantuml +class json::binary_t { + -- setters -- + +void set_subtype(std::uint64_t subtype) + +void clear_subtype() + -- getters -- + +std::uint64_t subtype() const + +bool has_subtype() const +} + +"std::vector" <|-- json::binary_t +``` + +By default, binary values are stored as `std::vector`. This type can be changed by providing a template +parameter to the `basic_json` type. To store binary subtypes, the storage type is extended and exposed as +`json::binary_t`: + +```cpp +auto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}); +auto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42); +``` + +There are several convenience functions to check and set the subtype: + +```cpp +binary.has_subtype(); // returns false +binary_with_subtype.has_subtype(); // returns true + +binary_with_subtype.clear_subtype(); +binary_with_subtype.has_subtype(); // returns true + +binary_with_subtype.set_subtype(42); +binary.set_subtype(23); + +binary.subtype(); // returns 23 +``` + +As `json::binary_t` is subclassing `std::vector`, all member functions are available: + +```cpp +binary.size(); // returns 4 +binary[1]; // returns 0xFE +``` + +JSON values can be constructed from `json::binary_t`: + +```cpp +json j = binary; +``` + +Binary values are primitive values just like numbers or strings: + +```cpp +j.is_binary(); // returns true +j.is_primitive(); // returns true +``` + +Given a binary JSON value, the `binary_t` can be accessed by reference as via `get_binary()`: + +```cpp +j.get_binary().has_subtype(); // returns true +j.get_binary().size(); // returns 4 +``` + +For convenience, binary JSON values can be constructed via `json::binary`: + +```cpp +auto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23); +auto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}); + +j2 == j; // returns true +j3.get_binary().has_subtype(); // returns false +j3.get_binary().subtype(); // returns std::uint64_t(-1) as j3 has no subtype +``` + + + +## Serialization + +Binary values are serialized differently according to the formats. + +### JSON + +JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. +Instead, binary values are serialized as an object with two keys: `bytes` holds an array of integers, and `subtype` +is an integer or `null`. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // serialize to standard output + std::cout << j.dump(2) << std::endl; + ``` + + Output: + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } + } + ``` + +!!! warning "No roundtrip for binary values" + + The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to + remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes. + +### BJData + +[BJData](binary_formats/bjdata.md) neither supports binary values nor subtypes, and proposes to serialize binary values +as array of uint8 values. This translation is implemented by the library. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 (will be ignored in BJData) + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to BJData + auto v = json::to_bjdata(j); + ``` + + `v` is a `std::vector` with the following 20 elements: + + ```c + 0x7B // '{' + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' + 0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U') + 0x5D // ']' + 0x7D // '}' + ``` + + The following code uses the type and size optimization for UBJSON: + + ```cpp + // convert to UBJSON using the size and type optimization + auto v = json::to_bjdata(j, true, true); + ``` + + The resulting vector has 22 elements; the optimization is not effective for examples with few values: + + ```c + 0x7B // '{' + 0x23 0x69 0x01 // '#' 'i' type of the array elements: unsigned integers + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' array + 0x24 0x55 // '$' 'U' type of the array elements: unsigned integers + 0x23 0x69 0x04 // '#' i 4 number of array elements + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that subtype (42) is **not** serialized and that UBJSON has **no binary type**, and deserializing `v` would + yield the following value: + + ```json + { + "binary": [202, 254, 186, 190] + } + ``` + +### BSON + +[BSON](binary_formats/bson.md) supports binary values and subtypes. If a subtype is given, it is used and added as +unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to BSON + auto v = json::to_bson(j); + ``` + + `v` is a `std::vector` with the following 22 elements: + + ```c + 0x16 0x00 0x00 0x00 // number of bytes in the document + 0x05 // binary value + 0x62 0x69 0x6E 0x61 0x72 0x79 0x00 // key "binary" + null byte + 0x04 0x00 0x00 0x00 // number of bytes + 0x2a // subtype + 0xCA 0xFE 0xBA 0xBE // content + 0x00 // end of the document + ``` + + Note that the serialization preserves the subtype, and deserializing `v` would yield the following value: + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } + } + ``` + +### CBOR + +[CBOR](binary_formats/cbor.md) supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary +value will be serialized as byte strings. The library will choose the smallest representation using the length of the +byte array. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to CBOR + auto v = json::to_cbor(j); + ``` + + `v` is a `std::vector` with the following 15 elements: + + ```c + 0xA1 // map(1) + 0x66 // text(6) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0xD8 0x2A // tag(42) + 0x44 // bytes(4) + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless + `json::cbor_tag_handler_t::ignore` or `json::cbor_tag_handler_t::store` is passed to `json::from_cbor`. + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": null + } + } + ``` + +### MessagePack + +[MessagePack](binary_formats/messagepack.md) supports binary values and subtypes. If a subtype is given, the ext family +is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, ext8, ext16, and +ext32. The subtype is then added as signed 8-bit integer. + +If no subtype is given, the bin family (bin8, bin16, bin32) is used. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to MessagePack + auto v = json::to_msgpack(j); + ``` + + `v` is a `std::vector` with the following 14 elements: + + ```c + 0x81 // fixmap1 + 0xA6 // fixstr6 + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0xD6 // fixext4 + 0x2A // subtype + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that the serialization preserves the subtype, and deserializing `v` would yield the following value: + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } + } + ``` + +### UBJSON + +[UBJSON](binary_formats/ubjson.md) neither supports binary values nor subtypes, and proposes to serialize binary values +as array of uint8 values. This translation is implemented by the library. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 (will be ignored in UBJSON) + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to UBJSON + auto v = json::to_ubjson(j); + ``` + + `v` is a `std::vector` with the following 20 elements: + + ```c + 0x7B // '{' + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' + 0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U') + 0x5D // ']' + 0x7D // '}' + ``` + + The following code uses the type and size optimization for UBJSON: + + ```cpp + // convert to UBJSON using the size and type optimization + auto v = json::to_ubjson(j, true, true); + ``` + + The resulting vector has 23 elements; the optimization is not effective for examples with few values: + + ```c + 0x7B // '{' + 0x24 // '$' type of the object elements + 0x5B // '[' array + 0x23 0x69 0x01 // '#' i 1 number of object elements + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x24 0x55 // '$' 'U' type of the array elements: unsigned integers + 0x23 0x69 0x04 // '#' i 4 number of array elements + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that subtype (42) is **not** serialized and that UBJSON has **no binary type**, and deserializing `v` would + yield the following value: + + ```json + { + "binary": [202, 254, 186, 190] + } + ``` diff --git a/json-develop/docs/mkdocs/docs/features/comments.md b/json-develop/docs/mkdocs/docs/features/comments.md new file mode 100644 index 0000000..61266d9 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/comments.md @@ -0,0 +1,83 @@ +# Comments + +This library does not support comments *by default*. It does so for three reasons: + +1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript. +2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012: + + > I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't. + + > Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser. + +3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this. + +However, you can pass set parameter `ignore_comments` to `#!c true` in the parse function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace. + +!!! example + + Consider the following JSON with comments. + + ```json + { + // update in 2006: removed Pluto + "planets": ["Mercury", "Venus", "Earth", "Mars", + "Jupiter", "Uranus", "Neptune" /*, "Pluto" */] + } + ``` + + When calling `parse` without additional argument, a parse error exception is thrown. If `ignore_comments` is set to `#! true`, the comments are ignored during parsing: + + ```cpp + #include + #include "json.hpp" + + using json = nlohmann::json; + + int main() + { + std::string s = R"( + { + // update in 2006: removed Pluto + "planets": ["Mercury", "Venus", "Earth", "Mars", + "Jupiter", "Uranus", "Neptune" /*, "Pluto" */] + } + )"; + + try + { + json j = json::parse(s); + } + catch (json::exception &e) + { + std::cout << e.what() << std::endl; + } + + json j = json::parse(s, + /* callback */ nullptr, + /* allow exceptions */ true, + /* ignore_comments */ true); + std::cout << j.dump(2) << '\n'; + } + ``` + + Output: + + ``` + [json.exception.parse_error.101] parse error at line 3, column 9: + syntax error while parsing object key - invalid literal; + last read: ' { /'; expected string literal + ``` + + ```json + { + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune" + ] + } + ``` diff --git a/json-develop/docs/mkdocs/docs/features/element_access/checked_access.md b/json-develop/docs/mkdocs/docs/features/element_access/checked_access.md new file mode 100644 index 0000000..c4023cc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/element_access/checked_access.md @@ -0,0 +1,91 @@ +# Checked access: at + +## Overview + +The [`at`](../../api/basic_json/at.md) member function performs checked access; that is, it returns a reference to the +desired value if it exists and throws a [`basic_json::out_of_range` exception](../../home/exceptions.md#out-of-range) +otherwise. + +??? example "Read access" + + Consider the following JSON value: + + ```json + { + "name": "Mary Smith", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + + Assume the value is parsed to a `json` variable `j`. + + | expression | value | + |-------------------------------|------------------------------------------------------------------------------| + | `#!cpp j` | `#!json {"name": "Mary Smith", "age": 42, "hobbies": ["hiking", "reading"]}` | + | `#!cpp j.at("name")` | `#!json "Mary Smith"` | + | `#!cpp j.at("age")` | `#!json 42` | + | `#!cpp j.at("hobbies")` | `#!json ["hiking", "reading"]` | + | `#!cpp j.at("hobbies").at(0)` | `#!json "hiking"` | + | `#!cpp j.at("hobbies").at(1)` | `#!json "reading"` | + +The return value is a reference, so it can be modified by the original value. + +??? example "Write access" + + ```cpp + j.at("name") = "John Smith"; + ``` + + This code produces the following JSON value: + + ```json + { + "name": "John Smith", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + +When accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is +non-existing, an exception is thrown. + +??? example "Accessing via invalid index or missing key" + + ```cpp + j.at("hobbies").at(3) = "cooking"; + ``` + + This code produces the following exception: + + ``` + [json.exception.out_of_range.401] array index 3 is out of range + ``` + + When you [extended diagnostic messages](../../home/exceptions.md#extended-diagnostic-messages) are enabled by + defining [`JSON_DIAGNOSTICS`](../../api/macros/json_diagnostics.md), the exception further gives information where + the key or index is missing or out of range. + + ``` + [json.exception.out_of_range.401] (/hobbies) array index 3 is out of range + ``` + +## Notes + + +!!! failure "Exceptions" + + - [`at`](../../api/basic_json/at.md) can only be used with objects (with a string argument) or with arrays (with a + numeric argument). For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error304) + is thrown. + - [`basic_json::out_of_range` exception](../../home/exceptions.md#out-of-range) exceptions are thrown if the + provided key is not found in an object or the provided index is invalid. + +## Summary + +| scenario | non-const value | const value | +|-----------------------------------|------------------------------------------------|------------------------------------------------| +| access to existing object key | reference to existing value is returned | const reference to existing value is returned | +| access to valid array index | reference to existing value is returned | const reference to existing value is returned | +| access to non-existing object key | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown | +| access to invalid array index | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown | diff --git a/json-develop/docs/mkdocs/docs/features/element_access/default_value.md b/json-develop/docs/mkdocs/docs/features/element_access/default_value.md new file mode 100644 index 0000000..02b4fea --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/element_access/default_value.md @@ -0,0 +1,32 @@ +# Access with default value: value + +## Overview + +In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. + +??? example + + Consider the following JSON value: + + ```json + { + "logOutput": "result.log", + "append": true + } + ``` + + Assume the value is parsed to a `json` variable `j`. + + | expression | value | + | ---------- | ----- | + | `#!cpp j` | `#!json {"logOutput": "result.log", "append": true}` | + | `#!cpp j.value("logOutput", "logfile.log")` | `#!json "result.log"` | + | `#!cpp j.value("append", true)` | `#!json true` | + | `#!cpp j.value("append", false)` | `#!json true` | + | `#!cpp j.value("logLevel", "verbose")` | `#!json "verbose"` | + +## Note + +!!! failure "Exceptions" + + - `value` can only be used with objects. For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error306) is thrown. diff --git a/json-develop/docs/mkdocs/docs/features/element_access/index.md b/json-develop/docs/mkdocs/docs/features/element_access/index.md new file mode 100644 index 0000000..0b39547 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/element_access/index.md @@ -0,0 +1,9 @@ +# Element Access + +There are many ways elements in a JSON value can be accessed: + +- unchecked access via [`operator[]`](unchecked_access.md) +- checked access via [`at`](checked_access.md) +- access with default value via [`value`](default_value.md) +- iterators +- JSON pointers diff --git a/json-develop/docs/mkdocs/docs/features/element_access/unchecked_access.md b/json-develop/docs/mkdocs/docs/features/element_access/unchecked_access.md new file mode 100644 index 0000000..39f06dc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/element_access/unchecked_access.md @@ -0,0 +1,112 @@ +# Unchecked access: operator[] + +## Overview + +Elements in a JSON object and a JSON array can be accessed via [`operator[]`](../../api/basic_json/operator%5B%5D.md) +similar to a `#!cpp std::map` and a `#!cpp std::vector`, respectively. + +??? example "Read access" + + Consider the following JSON value: + + ```json + { + "name": "Mary Smith", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + + Assume the value is parsed to a `json` variable `j`. + + | expression | value | + |-------------------------|------------------------------------------------------------------------------| + | `#!cpp j` | `#!json {"name": "Mary Smith", "age": 42, "hobbies": ["hiking", "reading"]}` | + | `#!cpp j["name"]` | `#!json "Mary Smith"` | + | `#!cpp j["age"]` | `#!json 42` | + | `#!cpp j["hobbies"]` | `#!json ["hiking", "reading"]` | + | `#!cpp j["hobbies"][0]` | `#!json "hiking"` | + | `#!cpp j["hobbies"][1]` | `#!json "reading"` | + +The return value is a reference, so it can modify the original value. In case the passed object key is non-existing, a +`#!json null` value is inserted which can be immediately be overwritten. + +??? example "Write access" + + ```cpp + j["name"] = "John Smith"; + j["maidenName"] = "Jones"; + ``` + + This code produces the following JSON value: + + ```json + { + "name": "John Smith", + "maidenName": "Jones", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + +When accessing an invalid index (i.e., an index greater than or equal to the array size), the JSON array is resized such +that the passed index is the new maximal index. Intermediate values are filled with `#!json null`. + +??? example "Filling up arrays with `#!json null` values" + + ```cpp + j["hobbies"][0] = "running"; + j["hobbies"][3] = "cooking"; + ``` + + This code produces the following JSON value: + + ```json + { + "name": "John Smith", + "maidenName": "Jones", + "age": 42, + "hobbies": ["running", "reading", null, "cooking"] + } + ``` + +## Notes + +!!! info "Design rationale" + + The library behaves differently to `#!cpp std::vector` and `#!cpp std::map`: + + - `#!cpp std::vector::operator[]` never inserts a new element. + - `#!cpp std::map::operator[]` is not available for const values. + + The type `#!cpp json` wraps all JSON value types. It would be impossible to remove + [`operator[]`](../../api/basic_json/operator%5B%5D.md) for const objects. At the same time, inserting elements for + non-const objects is really convenient as it avoids awkward `insert` calls. To this end, we decided to have an + inserting non-const behavior for both arrays and objects. + +!!! info + + The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no + exception is thrown. + +!!! danger + + - It is **undefined behavior** to access a const object with a non-existing key. + - It is **undefined behavior** to access a const array with an invalid index. + - In debug mode, an **assertion** will fire in both cases. You can disable assertions by defining the preprocessor + symbol `#!cpp NDEBUG` or redefine the macro [`JSON_ASSERT(x)`](../macros.md#json_assertx). See the documentation + on [runtime assertions](../assertions.md) for more information. + +!!! failure "Exceptions" + + `operator[]` can only be used with objects (with a string argument) or with arrays (with a numeric argument). For + other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error305) is thrown. + +## Summary + +| scenario | non-const value | const value | +|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------| +| access to existing object key | reference to existing value is returned | const reference to existing value is returned | +| access to valid array index | reference to existing value is returned | const reference to existing value is returned | +| access to non-existing object key | reference to newly inserted `#!json null` value is returned | **undefined behavior**; [runtime assertion](../assertions.md) in debug mode | +| access to invalid array index | reference to newly inserted `#!json null` value is returned; any index between previous maximal index and passed index are filled with `#!json null` | **undefined behavior**; [runtime assertion](../assertions.md) in debug mode | diff --git a/json-develop/docs/mkdocs/docs/features/enum_conversion.md b/json-develop/docs/mkdocs/docs/features/enum_conversion.md new file mode 100644 index 0000000..59ffbd5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/enum_conversion.md @@ -0,0 +1,61 @@ +# Specializing enum conversion + +By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an +enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be +undefined or a different enum value than was originally intended. + +It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below: + +```cpp +// example enum type declaration +enum TaskState { + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID=-1, +}; + +// map TaskState values to JSON as strings +NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, { + {TS_INVALID, nullptr}, + {TS_STOPPED, "stopped"}, + {TS_RUNNING, "running"}, + {TS_COMPLETED, "completed"}, +}) +``` + +The [`NLOHMANN_JSON_SERIALIZE_ENUM()` macro](../api/macros/nlohmann_json_serialize_enum.md) declares a set of +`to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code. + +## Usage + +```cpp +// enum to JSON as string +json j = TS_STOPPED; +assert(j == "stopped"); + +// json string to enum +json j3 = "running"; +assert(j3.get() == TS_RUNNING); + +// undefined json value to enum (where the first map entry above is the default) +json jPi = 3.14; +assert(jPi.get() == TS_INVALID ); +``` + +## Notes + +Just as in [Arbitrary Type Conversions](arbitrary_types.md) above, + +- [`NLOHMANN_JSON_SERIALIZE_ENUM()`](../api/macros/nlohmann_json_serialize_enum.md) MUST be declared in your enum type's + namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to + integer serialization. +- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions. + +Other Important points: + +- When using `get()`, undefined JSON values will default to the first pair specified in your map. Select this + default pair carefully. +- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the + map will be returned when converting to or from JSON. +- To disable the default serialization of enumerators as integers and force a compiler error instead, see [`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). diff --git a/json-develop/docs/mkdocs/docs/features/iterators.md b/json-develop/docs/mkdocs/docs/features/iterators.md new file mode 100644 index 0000000..ce627e0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/iterators.md @@ -0,0 +1,155 @@ +# Iterators + +## Overview + +A `basic_json` value is a container and allows access via iterators. Depending on the value type, `basic_json` stores zero or more values. + +As for other containers, `begin()` returns an iterator to the first value and `end()` returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, `begin()` will return `end()`. + +![Illustration from cppreference.com](../images/range-begin-end.svg) + +### Iteration order for objects + +When iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](types/index.md#key-order) for more information. + +??? example + + ```cpp + // create JSON object {"one": 1, "two": 2, "three": 3} + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + for (auto it = j.begin(); it != j.end(); ++it) + { + std::cout << *it << std::endl; + } + ``` + + Output: + + ```json + 1 + 3 + 2 + ``` + + The reason for the order is the lexicographic ordering of the object keys "one", "three", "two". + +### Access object key during iteration + +The JSON iterators have two member functions, `key()` and `value()` to access the object key and stored value, respectively. When calling `key()` on a non-object iterator, an [invalid_iterator.207](../home/exceptions.md#jsonexceptioninvalid_iterator207) exception is thrown. + +??? example + + ```cpp + // create JSON object {"one": 1, "two": 2, "three": 3} + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + for (auto it = j.begin(); it != j.end(); ++it) + { + std::cout << it.key() << " : " << it.value() << std::endl; + } + ``` + + Output: + + ```json + one : 1 + three : 3 + two : 2 + ``` + +### Range-based for loops + +C++11 allows using range-based for loops to iterate over a container. + +```cpp +for (auto it : j_object) +{ + // "it" is of type json::reference and has no key() member + std::cout << "value: " << it << '\n'; +} +``` + +For this reason, the `items()` function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator. + +```cpp +for (auto& el : j_object.items()) +{ + std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; +} +``` + +The items() function also allows using structured bindings (C++17): + +```cpp +for (auto& [key, val] : j_object.items()) +{ + std::cout << "key: " << key << ", value:" << val << '\n'; +} +``` + +!!! note + + When iterating over an array, `key()` will return the index of the element as string. For primitive types (e.g., numbers), `key()` returns an empty string. + +!!! warning + + Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See for more information. + +### Reverse iteration order + +`rbegin()` and `rend()` return iterators in the reverse sequence. + +![Illustration from cppreference.com](../images/range-rbegin-rend.svg) + +??? example + + ```cpp + json j = {1, 2, 3, 4}; + + for (auto it = j.rbegin(); it != j.rend(); ++it) + { + std::cout << *it << std::endl; + } + ``` + + Output: + + ```json + 4 + 3 + 2 + 1 + ``` + +### Iterating strings and binary values + +Note that "value" means a JSON value in this setting, not values stored in the underlying containers. That is, `*begin()` returns the complete string or binary array and is also safe the underlying string or binary array is empty. + +??? example + + ```cpp + json j = "Hello, world"; + for (auto it = j.begin(); it != j.end(); ++it) + { + std::cout << *it << std::endl; + } + ``` + + Output: + + ```json + "Hello, world" + ``` + +## Iterator invalidation + +| Operations | invalidated iterators | +|------------|-----------------------| +| `clear` | all | diff --git a/json-develop/docs/mkdocs/docs/features/json_patch.md b/json-develop/docs/mkdocs/docs/features/json_patch.md new file mode 100644 index 0000000..88c731a --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/json_patch.md @@ -0,0 +1,47 @@ +# JSON Patch and Diff + +## Patches + +JSON Patch ([RFC 6902](https://tools.ietf.org/html/rfc6902)) defines a JSON document structure for expressing a sequence +of operations to apply to a JSON document. With the `patch` function, a JSON Patch is applied to the current JSON value +by executing all operations from the patch. + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch.output" + ``` + +## Diff + +The library can also calculate a JSON patch (i.e., a **diff**) given two JSON values. + +!!! success "Invariant" + + For two JSON values *source* and *target*, the following code yields always true: + + ```cüü + source.patch(diff(source, target)) == target; + ``` + +??? example + + The following code shows how a JSON patch is created as a diff for two JSON values. + + ```cpp + --8<-- "examples/diff.cpp" + ``` + + Output: + + ```json + --8<-- "examples/diff.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/json_pointer.md b/json-develop/docs/mkdocs/docs/features/json_pointer.md new file mode 100644 index 0000000..04aeca5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/json_pointer.md @@ -0,0 +1,126 @@ +# JSON Pointer + +## Introduction + +The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address +structured values. A JSON Pointer is a string that identifies a specific value within a JSON document. + +Consider the following JSON document + +```json +{ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +} +``` + +Then every value inside the JSON document can be identified as follows: + +| JSON Pointer | JSON value | +|-------------------|----------------------------------------------------------------------------------| +| `` | `#!json {"array":["A","B","C"],"nested":{"one":1,"two":2,"three":[true,false]}}` | +| `/array` | `#!json ["A","B","C"]` | +| `/array/0` | `#!json A` | +| `/array/1` | `#!json B` | +| `/array/2` | `#!json C` | +| `/nested` | `#!json {"one":1,"two":2,"three":[true,false]}` | +| `/nested/one` | `#!json 1` | +| `/nested/two` | `#!json 2` | +| `/nested/three` | `#!json [true,false]` | +| `/nested/three/0` | `#!json true` | +| `/nested/three/1` | `#!json false` | + +Note `/` does not identify the root (i.e., the whole document), but an object entry with empty key `""`. See +[RFC 6901](https://tools.ietf.org/html/rfc6901) for more information. + +## JSON Pointer creation + +JSON Pointers can be created from a string: + +```cpp +json::json_pointer p = "/nested/one"; +``` + +Furthermore, a user-defined string literal can be used to achieve the same result: + +```cpp +auto p = "/nested/one"_json_pointer; +``` + +The escaping rules of [RFC 6901](https://tools.ietf.org/html/rfc6901) are implemented. See the +[constructor documentation](../api/json_pointer/json_pointer.md) for more information. + +## Value access + +JSON Pointers can be used in the [`at`](../api/basic_json/at.md), [`operator[]`](../api/basic_json/operator%5B%5D.md), +and [`value`](../api/basic_json/value.md) functions just like object keys or array indices. + +```cpp +// the JSON value from above +auto j = json::parse(R"({ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +})"); + +// access values +auto val = j["/"_json_pointer]; // {"array":["A","B","C"],...} +auto val1 = j["/nested/one"_json_pointer]; // 1 +auto val2 = j.at[json::json_pointer("/nested/three/1")]; // false +auto val3 = j.value[json::json_pointer("/nested/four", 0)]; // 0 +``` + +## Flatten / unflatten + +The library implements a function [`flatten`](../api/basic_json/flatten.md) to convert any JSON document into a JSON +object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or +null). + +```cpp +// the JSON value from above +auto j = json::parse(R"({ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +})"); + +// create flattened value +auto j_flat = j.flatten(); +``` + +The resulting value `j_flat` is: + +```json +{ + "/array/0": "A", + "/array/1": "B", + "/array/2": "C", + "/nested/one": 1, + "/nested/two": 2, + "/nested/three/0": true, + "/nested/three/1": false +} +``` + +The reverse function, [`unflatten`](../api/basic_json/unflatten.md) recreates the original value. + +```cpp +auto j_original = j_flat.unflatten(); +``` + +## See also + +- Class [`json_pointer`](../api/json_pointer/index.md) +- Function [`flatten`](../api/basic_json/flatten.md) +- Function [`unflatten`](../api/basic_json/unflatten.md) +- [JSON Patch](json_patch.md) diff --git a/json-develop/docs/mkdocs/docs/features/macros.md b/json-develop/docs/mkdocs/docs/features/macros.md new file mode 100644 index 0000000..1be95d3 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/macros.md @@ -0,0 +1,153 @@ +# Supported Macros + +Some aspects of the library can be configured by defining preprocessor macros before including the `json.hpp` header. +See also the [API documentation for macros](../api/macros/index.md) for examples and more information. + +## `JSON_ASSERT(x)` + +This macro controls which code is executed for [runtime assertions](assertions.md) of the library. + +See [full documentation of `JSON_ASSERT(x)`](../api/macros/json_assert.md). + +## `JSON_CATCH_USER(exception)` + +This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library. + +See [full documentation of `JSON_CATCH_USER(exception)`](../api/macros/json_throw_user.md). + +## `JSON_DIAGNOSTICS` + +This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable +(default). + +When enabled, exception messages contain a [JSON Pointer](json_pointer.md) to the JSON value that triggered the +exception, see [Extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) for an example. Note +that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead. + +The diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets +`JSON_DIAGNOSTICS` accordingly. + +See [full documentation of `JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). + +## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20` + +The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` +support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ +standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is +unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be +detected incorrectly. + +See [full documentation of `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, and `JSON_HAS_CPP_20`](../api/macros/json_has_cpp_11.md). + +## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM` + +When compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support +for filesystem is limited, the library tries to detect whether ``/`std::filesystem` (`JSON_HAS_FILESYSTEM`) +or ``/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used. +To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`. + +See [full documentation of `JSON_HAS_FILESYSTEM` and `JSON_HAS_EXPERIMENTAL_FILESYSTEM`](../api/macros/json_has_filesystem.md). + +## `JSON_NOEXCEPTION` + +Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. + +See [full documentation of `JSON_NOEXCEPTION`](../api/macros/json_noexception.md). + +## `JSON_DISABLE_ENUM_SERIALIZATION` + +When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md). + +See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). + +## `JSON_NO_IO` + +When defined, headers ``, ``, ``, ``, and `` are not included and parse functions +relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for +security reasons (e.g., Intel Software Guard Extensions (SGX)). + +See [full documentation of `JSON_NO_IO`](../api/macros/json_no_io.md). + +## `JSON_SKIP_LIBRARY_VERSION_CHECK` + +When defined, the library will not create a compiler warning when a different version of the library was already +included. + +See [full documentation of `JSON_SKIP_LIBRARY_VERSION_CHECK`](../api/macros/json_skip_library_version_check.md). + +## `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK` + +When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to +use the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. + +See [full documentation of `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`](../api/macros/json_skip_unsupported_compiler_check.md). + +## `JSON_THROW_USER(exception)` + +This macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. + +See [full documentation of `JSON_THROW_USER(exception)`](../api/macros/json_throw_user.md). + +## `JSON_TRY_USER` + +This macro overrides `#!cpp try` calls inside the library. + +See [full documentation of `JSON_TRY_USER`](../api/macros/json_throw_user.md). + +## `JSON_USE_IMPLICIT_CONVERSIONS` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. + +See [full documentation of `JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md). + +## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)` + +This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as +serialization and (2) want to use the member variable names as object keys in that object. + +The macro is to be defined inside the class/struct to create code for. Unlike +[`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](#nlohmann_define_type_non_intrusivetype-member), it can access private members. +The first parameter is the name of the class/struct, and all remaining parameters name the members. + +See [full documentation of `NLOHMANN_DEFINE_TYPE_INTRUSIVE`](../api/macros/nlohmann_define_type_intrusive.md). + +## `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)` + +This macro is similar to `NLOHMANN_DEFINE_TYPE_INTRUSIVE`. It will not throw an exception in `from_json()` due to a +missing value in the JSON object, but can throw due to a mismatched type. The `from_json()` function default constructs +an object and uses its values as the defaults when calling the [`value`](../api/basic_json/value.md) function. + +See [full documentation of `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT`](../api/macros/nlohmann_define_type_intrusive.md). + +## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)` + +This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as +serialization and (2) want to use the member variable names as object keys in that object. + +The macro is to be defined inside the namespace of the class/struct to create code for. Private members cannot be +accessed. Use [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](#nlohmann_define_type_intrusivetype-member) in these scenarios. The +first parameter is the name of the class/struct, and all remaining parameters name the members. + +See [full documentation of `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](../api/macros/nlohmann_define_type_non_intrusive.md). + +## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)` + +This macro is similar to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`. It will not throw an exception in `from_json()` due to a +missing value in the JSON object, but can throw due to a mismatched type. The `from_json()` function default constructs +an object and uses its values as the defaults when calling the [`value`](../api/basic_json/value.md) function. + +See [full documentation of `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`](../api/macros/nlohmann_define_type_non_intrusive.md). + +## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)` + +This macro simplifies the serialization/deserialization of enum types. See +[Specializing enum conversion](enum_conversion.md) for more information. + +See [full documentation of `NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md). + +## `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, `NLOHMANN_JSON_VERSION_PATCH` + +These macros are defined by the library and contain the version numbers according to +[Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +See [full documentation of `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and `NLOHMANN_JSON_VERSION_PATCH`](../api/macros/nlohmann_json_version_major.md). diff --git a/json-develop/docs/mkdocs/docs/features/merge_patch.md b/json-develop/docs/mkdocs/docs/features/merge_patch.md new file mode 100644 index 0000000..84e0ab0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/merge_patch.md @@ -0,0 +1,20 @@ +# JSON Merge Patch + +The library supports JSON Merge Patch ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. +The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value. + +Instead of using [JSON Pointer](json_pointer.md) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. + +??? example + + The following code shows how a JSON Merge Patch is applied to a JSON document. + + ```cpp + --8<-- "examples/merge_patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/merge_patch.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/namespace.md b/json-develop/docs/mkdocs/docs/features/namespace.md new file mode 100644 index 0000000..8cee2cc --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/namespace.md @@ -0,0 +1,93 @@ +# `nlohmann` Namespace + +The 3.11.0 release introduced an +[inline namespace](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) to allow different parts of +a codebase to safely use different versions of the JSON library as long as they never exchange instances of library +types. + +## Structure + +The complete default namespace name is derived as follows: + +- The root namespace is always `nlohmann`. +- The inline namespace starts with `json_abi` and is followed by serveral optional ABI tags according to the value of + these ABI-affecting macros, in order: + - [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) defined non-zero appends `_diag`. + - [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md) + defined non-zero appends `_ldvcmp`. +- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by + underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component) + below. + +For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defined to `1` is: + +```cpp +nlohmann::json_abi_diag_v3_11_2 +``` + +## Purpose + +Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different +definitions of [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This is illustrated in the diagram below. + +```plantuml +[**nlohmann_json (v3.10.5)**\nJSON_DIAGNOSTICS=0] as [json] +[**nlohmann_json (v3.10.5)**\nJSON_DIAGNOSTICS=1] as [json_diag] +[**some_library**] as [library] +[**application**] as [app] + +[library] ..|> [json] +[app] ..|> [json_diag] +[app] ..|>[library] +``` + +In releases prior to 3.11.0, mixing any version of the JSON library with different `JSON_DIAGNOSTICS` settings would +result in a crashing application. If `some_library` never passes instances of JSON library types to the application, +this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names. + +## Limitations + +Neither the compiler nor the linker will issue as much as a warning when translation units – intended to be linked +together and that include different versions and/or configurations of the JSON library – exchange and use library +types. + +There is an exception when forward declarations are used (i.e., when including `json_fwd.hpp`) in which case the linker +may complain about undefined references. + +## Disabling the version component + +Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and +recommends that all parts of a codebase exchanging library types be built with the same version. Users can, **at their +own risk**, disable the version component of the linline namespace, allowing different versions – but not +configurations – to be used in cases where the linker would otherwise output undefined reference errors. + +To do so, define [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md) to `1`. + +This applies to version 3.11.2 and above only, versions 3.11.0 and 3.11.1 can apply the technique described in the next +section to emulate the effect of the `NLOHMANN_JSON_NAMESPACE_NO_VERSION` macro. + +!!! danger "Use at your own risk" + + Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect + behavior. You have been warned! +## Disabling the inline namespace completely + +When interoperability with code using a pre-3.11.0 version of the library is required, users can, **at their own risk** +restore the old namespace layout by redefining +[`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md) as +follows: + +```cpp +#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann { +#define NLOHMANN_JSON_NAMESPACE_END } +``` + +!!! danger "Use at your own risk" + + Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You + have been warned! + +## Version history + +- Introduced inline namespace (`json_v3_11_0[_abi-tag]*`) in version 3.11.0. +- Changed structure of inline namespace in version 3.11.2. diff --git a/json-develop/docs/mkdocs/docs/features/object_order.md b/json-develop/docs/mkdocs/docs/features/object_order.md new file mode 100644 index 0000000..3ee16a9 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/object_order.md @@ -0,0 +1,109 @@ +# Object Order + +The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys. + +## Default behavior: sort keys + +The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**. + +??? example + + ```cpp + #include + #include "json.hpp" + + using json = nlohmann::json; + + int main() + { + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + std::cout << j.dump(2) << '\n'; + } + ``` + + Output: + + ```json + { + "one": 1, + "three": 3, + "two": 2 + } + ``` + +## Alternative behavior: preserve insertion order + +If you do want to preserve the **insertion order**, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179). + +??? example + + ```cpp + --8<-- "examples/ordered_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_json.output" + ``` + +Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). + +### Notes on parsing + +Note that you also need to call the right [`parse`](../api/basic_json/parse.md) function when reading from a file. +Assume file `input.json` contains the JSON object above: + +```json +{ + "one": 1, + "two": 2, + "three": 3 +} +``` + +!!! success "Right way" + + The following code correctly calls the `parse` function from `nlohmann::ordered_json`: + + ```cpp + std::ifstream i("input.json"); + auto j = nlohmann::ordered_json::parse(i); + std::cout << j.dump(2) << std::endl; + ``` + + The output will be: + + ```json + { + "one": 1, + "two": 2, + "three": 3 + } + ``` + +??? failure "Wrong way" + + The following code incorrectly calls the `parse` function from `nlohmann::json` which does not preserve the + insertion order, but sorts object keys. Assigning the result to `nlohmann::ordered_json` compiles, but does not + restore the order from the input file. + + ```cpp + std::ifstream i("input.json"); + nlohmann::ordered_json j = nlohmann::json::parse(i); + std::cout << j.dump(2) << std::endl; + ``` + + The output will be: + + ```json + { + "one": 1, + "three": 3 + "two": 2, + } + ``` diff --git a/json-develop/docs/mkdocs/docs/features/parsing/index.md b/json-develop/docs/mkdocs/docs/features/parsing/index.md new file mode 100644 index 0000000..2949352 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/parsing/index.md @@ -0,0 +1,13 @@ +# Parsing + +!!! note + + This page is under construction. + +## Input + +## SAX vs. DOM parsing + +## Exceptions + +See [parsing and exceptions](parse_exceptions.md). diff --git a/json-develop/docs/mkdocs/docs/features/parsing/json_lines.md b/json-develop/docs/mkdocs/docs/features/parsing/json_lines.md new file mode 100644 index 0000000..659d317 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/parsing/json_lines.md @@ -0,0 +1,49 @@ +# JSON Lines + +The [JSON Lines](https://jsonlines.org) format is a text format of newline-delimited JSON. In particular: + +1. The input must be UTF-8 encoded. +2. Every line must be a valid JSON value. +3. The line separator must be `\n`. As `\r` is silently ignored, `\r\n` is also supported. +4. The final character may be `\n`, but is not required to be one. + +!!! example "JSON Text example" + + ```json + {"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} + {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} + {"name": "May", "wins": []} + {"name": "Deloise", "wins": [["three of a kind", "5♣"]]} + ``` + +JSON Lines input with more than one value is treated as invalid JSON by the [`parse`](../../api/basic_json/parse.md) or +[`accept`](../../api/basic_json/accept.md) functions. To process it line by line, functions like +[`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) can be used: + +!!! example "Example: Parse JSON Text input line by line" + + The example below demonstrates how JSON Lines can be processed. + + ```cpp + --8<-- "examples/json_lines.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_lines.output" + ``` + +!!! warning "Note" + + Using [`operator>>`](../../api/operator_gtgt.md) like + + ```cpp + json j; + while (input >> j) + { + std::cout << j << std::endl; + } + ``` + + with a JSON Lines input does not work, because the parser will try to parse one value after the last one. diff --git a/json-develop/docs/mkdocs/docs/features/parsing/parse_exceptions.md b/json-develop/docs/mkdocs/docs/features/parsing/parse_exceptions.md new file mode 100644 index 0000000..61c0ff2 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/parsing/parse_exceptions.md @@ -0,0 +1,121 @@ +# Parsing and Exceptions + +When the input is not valid JSON, an exception of type [`parse_error`](../../home/exceptions.md#parse-errors) is thrown. +This exception contains the position in the input where the error occurred, together with a diagnostic message and the +last read input token. The exceptions page contains a +[list of examples for parse error exceptions](../../home/exceptions.md#parse-errors). In case you process untrusted +input, always enclose your code with a `#!cpp try`/`#!cpp catch` block, like + +```cpp +json j; +try +{ + j = json::parse(my_input); +} +catch (json::parse_error& ex) +{ + std::cerr << "parse error at byte " << ex.byte << std::endl; +} +``` + +In case exceptions are undesired or not supported by the environment, there are different ways to proceed: + + +## Switch off exceptions + +The `parse()` function accepts a `#!cpp bool` parameter `allow_exceptions` which controls whether an exception is +thrown when a parse error occurs (`#!cpp true`, default) or whether a discarded value should be returned +(`#!cpp false`). + +```cpp +json j = json::parse(my_input, nullptr, false); +if (j.is_discarded()) +{ + std::cerr << "parse error" << std::endl; +} +``` + +Note there is no diagnostic information available in this scenario. + +## Use accept() function + +Alternatively, function `accept()` can be used which does not return a `json` value, but a `#!cpp bool` indicating +whether the input is valid JSON. + +```cpp +if (!json::accept(my_input)) +{ + std::cerr << "parse error" << std::endl; +} +``` + +Again, there is no diagnostic information available. + + +## User-defined SAX interface + +Finally, you can implement the [SAX interface](sax_interface.md) and decide what should happen in case of a parse error. + +This function has the following interface: + +```cpp +bool parse_error(std::size_t position, + const std::string& last_token, + const json::exception& ex); +``` + +The return value indicates whether the parsing should continue, so the function should usually return `#!cpp false`. + +??? example + + ```cpp + #include + #include "json.hpp" + + using json = nlohmann::json; + + class sax_no_exception : public nlohmann::detail::json_sax_dom_parser + { + public: + sax_no_exception(json& j) + : nlohmann::detail::json_sax_dom_parser(j, false) + {} + + bool parse_error(std::size_t position, + const std::string& last_token, + const json::exception& ex) + { + std::cerr << "parse error at input byte " << position << "\n" + << ex.what() << "\n" + << "last read: \"" << last_token << "\"" + << std::endl; + return false; + } + }; + + int main() + { + std::string myinput = "[1,2,3,]"; + + json result; + sax_no_exception sax(result); + + bool parse_result = json::sax_parse(myinput, &sax); + if (!parse_result) + { + std::cerr << "parsing unsuccessful!" << std::endl; + } + + std::cout << "parsed value: " << result << std::endl; + } + ``` + + Output: + + ``` + parse error at input byte 8 + [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal + last read: "3,]" + parsing unsuccessful! + parsed value: [1,2,3] + ``` diff --git a/json-develop/docs/mkdocs/docs/features/parsing/parser_callbacks.md b/json-develop/docs/mkdocs/docs/features/parsing/parser_callbacks.md new file mode 100644 index 0000000..ef076d1 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/parsing/parser_callbacks.md @@ -0,0 +1,83 @@ +# Parser Callbacks + +## Overview + +With a parser callback function, the result of parsing a JSON text can be influenced. When passed to `parse`, it is +called on certain events (passed as `parse_event_t` via parameter `event`) with a set recursion depth `depth` and +context JSON value `parsed`. The return value of the callback function is a boolean indicating whether the element that +emitted the callback shall be kept or not. + +The type of the callback function is: + +```cpp +template +using parser_callback_t = + std::function; +``` + + +## Callback event types + +We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following +table describes the values of the parameters `depth`, `event`, and `parsed`. + +| parameter `event` | description | parameter `depth` | parameter `parsed` | +|-------------------------------|-----------------------------------------------------------|-------------------------------------------|----------------------------------| +| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded | +| `parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key | +| `parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object | +| `parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded | +| `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | +| `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | + +??? example + + When parsing the following JSON text, + + ```json + { + "name": "Berlin", + "location": [ + 52.519444, + 13.406667 + ] + } + ``` + + these calls are made to the callback function: + + | event | depth | parsed | + | -------------- | ----- | ------ | + | `object_start` | 0 | *discarded* | + | `key` | 1 | `#!json "name"` | + | `value` | 1 | `#!json "Berlin"` | + | `key` | 1 | `#!json "location"` | + | `array_start` | 1 | *discarded* | + | `value` | 2 | `#!json 52.519444` | + | `value` | 2 | `#!json 13.406667` | + | `array_end` | 1 | `#!json [52.519444,13.406667]` | + | `object_end` | 0 | `#!json {"location":[52.519444,13.406667],"name":"Berlin"}` | + +## Return value + +Discarding a value (i.e., returning `#!c false`) has different effects depending on the context in which the function +was called: + +- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never + read. +- In case a value outside a structured type is skipped, it is replaced with `#!json null`. This case happens if the + top-level element is skipped. + +??? example + + The example below demonstrates the `parse()` function with and without callback function. + + ```cpp + --8<-- "examples/parse__string__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__string__parser_callback_t.output" + ``` diff --git a/json-develop/docs/mkdocs/docs/features/parsing/sax_interface.md b/json-develop/docs/mkdocs/docs/features/parsing/sax_interface.md new file mode 100644 index 0000000..0796a55 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/parsing/sax_interface.md @@ -0,0 +1,73 @@ +# SAX Interface + +The library uses a SAX-like interface with the following functions: + +```plantuml +interface json::sax_t { + + {abstract} bool null() + + + {abstract} bool boolean(bool val) + + + {abstract} bool number_integer(number_integer_t val) + + {abstract} bool number_unsigned(number_unsigned_t val) + + + {abstract} bool number_float(number_float_t val, const string_t& s) + + + {abstract} bool string(string_t& val) + + {abstract} bool binary(binary_t& val) + + + {abstract} bool start_object(std::size_t elements) + + {abstract} bool end_object() + + {abstract} bool start_array(std::size_t elements) + + {abstract} bool end_array() + + {abstract} bool key(string_t& val) + + + {abstract} bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) +} +``` + +```cpp +// called when null is parsed +bool null(); + +// called when a boolean is parsed; value is passed +bool boolean(bool val); + +// called when a signed or unsigned integer number is parsed; value is passed +bool number_integer(number_integer_t val); +bool number_unsigned(number_unsigned_t val); + +// called when a floating-point number is parsed; value and original string is passed +bool number_float(number_float_t val, const string_t& s); + +// called when a string is parsed; value is passed and can be safely moved away +bool string(string_t& val); +// called when a binary value is parsed; value is passed and can be safely moved away +bool binary(binary& val); + +// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known) +bool start_object(std::size_t elements); +bool end_object(); +bool start_array(std::size_t elements); +bool end_array(); +// called when an object key is parsed; value is passed and can be safely moved away +bool key(string_t& val); + +// called when a parse error occurs; byte position, the last token, and an exception is passed +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex); +``` + +The return value of each function determines whether parsing should proceed. + +To implement your own SAX handler, proceed as follows: + +1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax` as base class, but you can also use any class where the functions described above are implemented and public. +2. Create an object of your SAX interface class, e.g. `my_sax`. +3. Call `#!cpp bool json::sax_parse(input, &my_sax);` where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface. + +Note the `sax_parse` function only returns a `#!cpp bool` indicating the result of the last executed SAX event. It does not return `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file `json_sax.hpp`. + +## See also + +- [json_sax](../../api/json_sax/index.md) - documentation of the SAX interface +- [sax_parse](../../api/basic_json/sax_parse.md) - SAX parser diff --git a/json-develop/docs/mkdocs/docs/features/types/index.md b/json-develop/docs/mkdocs/docs/features/types/index.md new file mode 100644 index 0000000..d9dfcc2 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/types/index.md @@ -0,0 +1,269 @@ +# Types + +This page gives an overview how JSON values are stored and how this can be configured. + +## Overview + +By default, JSON values are stored as follows: + +| JSON type | C++ type | +|-----------|-----------------------------------------------| +| object | `std::map` | +| array | `std::vector` | +| null | `std::nullptr_t` | +| string | `std::string` | +| boolean | `bool` | +| number | `std::int64_t`, `std::uint64_t`, and `double` | + +Note there are three different types for numbers - when parsing JSON text, the best fitting type is chosen. + +## Storage + +```plantuml +enum value_t { + null + object + array + string + boolean + number_integer + number_unsigned + number_float + binary + discarded +} + +class json_value << (U,orchid) >> { + object_t* object + array_t* array + string_t* string + binary_t* binary + boolean_t boolean + number_integer_t number_integer + number_unsigned_t number_unsigned + number_float_t number_float +} + +class basic_json { + -- type and value -- + value_t m_type + json_value m_value + -- derived types -- + + typedef object_t + + typedef array_t + + typedef binary_t + + typedef boolean_t + + typedef number_integer_t + + typedef number_unsigned_t + + typedef number_float_t +} + +basic_json .. json_value +basic_json .. value_t +``` + +## Template arguments + +The data types to store a JSON value are derived from the template arguments passed to class `basic_json`: + +```cpp +template< + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer, + class BinaryType = std::vector +> +class basic_json; +``` + +Type `json` is an alias for `basic_json<>` and uses the default types. + +From the template arguments, the following types are derived: + +```cpp +using object_comparator_t = std::less<>; +using object_t = ObjectType>>; + +using array_t = ArrayType>; + +using string_t = StringType; + +using boolean_t = BooleanType; + +using number_integer_t = NumberIntegerType; +using number_unsigned_t = NumberUnsignedType; +using number_float_t = NumberFloatType; + +using binary_t = nlohmann::byte_container_with_subtype; +``` + + +## Objects + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: + +> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array. + +### Default type + +With the default values for *ObjectType* (`std::map`), *StringType* (`std::string`), and *AllocatorType* (`std::allocator`), the default value for `object_t` is: + +```cpp +std::map< + std::string, // key_type + basic_json, // value_type + std::less<>, // key_compare + std::allocator> // allocator_type +> +``` + +### Behavior + +The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following behavior: + +- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings. +- When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, `#!json {"key": 2, "key": 1}` could be equal to either `#!json {"key": 1}` or `#!json {"key": 2}`. +- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see `dump`) in this order. For instance, both `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be stored and serialized as `#!json {"a": 2, "b": 1}`. +- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be treated as equal. + +### Key order + +The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects. + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON object. + +### Storage + +Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type `object_t*` must be dereferenced. + + +## Arrays + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: + +> An array is an ordered sequence of zero or more values. + +### Default type + +With the default values for *ArrayType* (`std::vector`) and *AllocatorType* (`std::allocator`), the default value for `array_t` is: + +```cpp +std::vector< + basic_json, // value_type + std::allocator // allocator_type +> +``` + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON array. + +### Storage + +Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type `array_t*` must be dereferenced. + + +## Strings + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: + +> A string is a sequence of zero or more Unicode characters. + +Unicode values are split by the JSON class into byte-sized characters during deserialization. + +### Default type + +With the default values for *StringType* (`std::string`), the default value for `string_t` is `#!cpp std::string`. + +### Encoding + +Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return the number of **bytes** in the string rather than the number of characters or glyphs. + +### String comparison + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. + +This implementation is interoperable as it does compare strings code unit by code unit. + +### Storage + +String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type `string_t*` must be dereferenced. + + +## Booleans + +[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`. + +### Default type + +With the default values for *BooleanType* (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`. + +### Storage + +Boolean values are stored directly inside a `basic_json` type. + +## Numbers + +See the [number handling](number_handling.md) article for a detailed discussion on how numbers are handled by this library. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: + +> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different types, `number_integer_t`, `number_unsigned_t`, and `number_float_t` are used. + +### Default types + +With the default values for *NumberIntegerType* (`std::int64_t`), the default value for `number_integer_t` is `std::int64_t`. +With the default values for *NumberUnsignedType* (`std::uint64_t`), the default value for `number_unsigned_t` is `std::uint64_t`. +With the default values for *NumberFloatType* (`#!cpp double`), the default value for `number_float_t` is `#!cpp double`. + +### Default behavior + +- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer literal `#!c 010` will be serialized to `#!c 8`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `#!json null`. + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `#!c 9223372036854775807` (`INT64_MAX`) and the minimal integer number that can be stored is `#!c -9223372036854775808` (`INT64_MIN`). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_unsigned_t` or `number_float_t`. + +When the default type is used, the maximal unsigned integer number that can be stored is `#!c 18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `#!c 0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_integer_t` or `number_float_t`. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: + +> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange of the exactly supported range [`INT64_MIN`, `INT64_MAX`], this class's integer type is interoperable. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. + +This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than `#!c -1.79769313486232e+308` and values greater than `#!c 1.79769313486232e+308` will be stored as NaN internally and be serialized to `#!json null`. + +### Storage + +Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a `basic_json` type. diff --git a/json-develop/docs/mkdocs/docs/features/types/number_handling.md b/json-develop/docs/mkdocs/docs/features/types/number_handling.md new file mode 100644 index 0000000..03d8c9c --- /dev/null +++ b/json-develop/docs/mkdocs/docs/features/types/number_handling.md @@ -0,0 +1,328 @@ +# Number Handling + +This document describes how the library is handling numbers. + +## Background + +This section briefly summarizes how the JSON specification describes how numbers should be handled. + +### JSON number syntax + +JSON defines the syntax of numbers as follows: + +!!! quote "[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6" + + The representation of numbers is similar to that used in most + programming languages. A number is represented in base 10 using + decimal digits. It contains an integer component that may be + prefixed with an optional minus sign, which may be followed by a + fraction part and/or an exponent part. Leading zeros are not + allowed. + + A fraction part is a decimal point followed by one or more digits. + + An exponent part begins with the letter E in uppercase or lowercase, + which may be followed by a plus or minus sign. The E and optional + sign are followed by one or more digits. + +The following railroad diagram from [json.org](https://json.org) visualizes the number syntax: + +![Syntax for JSON numbers](../../images/json_syntax_number.png) + +### Number interoperability + +On number interoperability, the following remarks are made: + +!!! quote "[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6" + + This specification allows implementations to set limits on the range + and precision of numbers accepted. Since software that implements + IEEE 754 binary64 (double precision) numbers [IEEE754] is generally + available and widely used, good interoperability can be achieved by + implementations that expect no more precision or range than these + provide, in the sense that implementations will approximate JSON + numbers within the expected precision. A JSON number such as 1E400 + or 3.141592653589793238462643383279 may indicate potential + interoperability problems, since it suggests that the software that + created it expects receiving software to have greater capabilities + for numeric magnitude and precision than is widely available. + + Note that when such software is used, numbers that are integers and + are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the + sense that implementations will agree exactly on their numeric + values. + +## Library implementation + +This section describes how the above number specification is implemented by this library. + +### Number storage + +In the default [`json`](../../api/json.md) type, numbers are stored as `#!c std::uint64_t`, `#!c std::int64_t`, and +`#!c double`, respectively. Thereby, `#!c std::uint64_t` and `#!c std::int64_t` are used only if they can store the +number without loss of precision. If this is impossible (e.g., if the number is too large), the number is stored as +`#!c double`. + +!!! info "Notes" + + - Numbers with a decimal digit or scientific notation are always stored as `#!c double`. + - The number types can be changed, see [Template number types](#template-number-types). + - As of version 3.9.1, the conversion is realized by + [`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul), + [`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and + [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively. + +!!! example "Examples" + + - Integer `#!c -12345678912345789123456789` is smaller than `#!c INT64_MIN` and will be stored as floating-point + number `#!c -1.2345678912345788e+25`. + - Integer `#!c 1E3` will be stored as floating-point number `#!c 1000.0`. + +### Number limits + +- Any 64-bit signed or unsigned integer can be stored without loss of precision. +- Numbers exceeding the limits of `#!c double` (i.e., numbers that after conversion via +[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) are not satisfying +[`std::isfinite`](https://en.cppreference.com/w/cpp/numeric/math/isfinite) such as `#!c 1E400`) will throw exception +[`json.exception.out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406) during parsing. +- Floating-point numbers are rounded to the next number representable as `double`. For instance +`#!c 3.141592653589793238462643383279` is stored as [`0x400921fb54442d18`](https://float.exposed/0x400921fb54442d18). +This is the same behavior as the code `#!c double x = 3.141592653589793238462643383279;`. + +!!! success "Interoperability" + + - The library interoperable with respect to the specification, because its supported range $[-2^{63}, 2^{64}-1]$ is + larger than the described range $[-2^{53}+1, 2^{53}-1]$. + - All integers outside the range $[-2^{63}, 2^{64}-1]$, as well as floating-point numbers are stored as `double`. + This also concurs with the specification above. + +### Zeros + +The JSON number grammar allows for different ways to express zero, and this library will store zeros differently: + +| Literal | Stored value and type | Serialization | +|---------|------------------------|---------------| +| `0` | `#!c std::uint64_t(0)` | `0` | +| `-0` | `#!c std::int64_t(0)` | `0` | +| `0.0` | `#!c double(0.0)` | `0.0` | +| `-0.0` | `#!c double(-0.0)` | `-0.0` | +| `0E0` | `#!c double(0.0)` | `0.0` | +| `-0E0` | `#!c double(-0.0)` | `-0.0` | + +That is, `-0` is stored as a signed integer, but the serialization does not reproduce the `-`. + +### Number serialization + +- Integer numbers are serialized as is; that is, no scientific notation is used. +- Floating-point numbers are serialized as specified by the `#!c %g` printf modifier with + [`std::numeric_limits::max_digits10`](https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10) + significant digits. The rationale is to use the shortest representation while still allow round-tripping. + +!!! hint "Notes regarding precision of floating-point numbers" + + As described above, floating-point numbers are rounded to the nearest double and serialized with the shortest + representation to allow round-tripping. This can yield confusing examples: + + - The serialization can have fewer decimal places than the input: `#!c 2555.5599999999999` will be serialized as + `#!c 2555.56`. The reverse can also be true. + - The serialization can be in scientific notation even if the input is not: `#!c 0.0000972439793401814` will be + serialized as `#!c 9.72439793401814e-05`. The reverse can also be true: `#!c 12345E-5` will be serialized as + `#!c 0.12345`. + - Conversions from `#!c float` to `#!c double` can also introduce rounding errors: + ```cpp + float f = 0.3; + json j = f; + std::cout << j << '\n'; + ``` + yields `#!c 0.30000001192092896`. + + All examples here can be reproduced by passing the original double value to + + ```cpp + std::printf("%.*g\n", std::numeric_limits::max_digits10, double_value); + ``` + +#### NaN handling + +NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded: + +!!! quote "[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6" + + Numeric values that cannot be represented in the grammar below (such + as Infinity and NaN) are not permitted. + +That is, there is no way to *parse* a NaN value. However, NaN values can be stored in a JSON value by assignment. + +This library serializes NaN values as `#!js null`. This corresponds to the behavior of JavaScript's +[`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) function. + +!!! example + + The following example shows how a NaN value is stored in a `json` value. + + ```cpp + int main() + { + double val = std::numeric_limits::quiet_NaN(); + std::cout << "val=" << val << std::endl; + json j = val; + std::cout << "j=" << j.dump() << std::endl; + val = j; + std::cout << "val=" << val << std::endl; + } + ``` + + output: + + ``` + val=nan + j=null + val=nan + ``` + +### Number comparison + +Floating-point inside JSON values numbers are compared with `#!c json::number_float_t::operator==` which is +`#!c double::operator==` by default. + +!!! example "Alternative comparison functions" + + To compare floating-point while respecting an epsilon, an alternative + [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) + could be used, for instance + + ```cpp + template::value, T>::type> + inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept + { + return std::abs(a - b) <= epsilon; + } + ``` + Or you can self-define an operator equal function like this: + + ```cpp + bool my_equal(const_reference lhs, const_reference rhs) + { + const auto lhs_type lhs.type(); + const auto rhs_type rhs.type(); + if (lhs_type == rhs_type) + { + switch(lhs_type) + { + // self_defined case + case value_t::number_float: + return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); + + // other cases remain the same with the original + ... + } + } + ... + } + ``` + + (see [#703](https://github.com/nlohmann/json/issues/703) for more information.) + +!!! note + + NaN values never compare equal to themselves or to other NaN values. See [#514](https://github.com/nlohmann/json/issues/514). + +### Number conversion + +Just like the C++ language itself, the `get` family of functions allows conversions between unsigned and signed +integers, and between integers and floating-point values to integers. This behavior may be surprising. + +!!! warning "Unconditional number conversions" + + ```cpp hl_lines="3" + double d = 42.3; // non-integer double value 42.3 + json jd = d; // stores double value 42.3 + std::int64_t i = jd.get(); // now i==42; no warning or error is produced + ``` + + Note the last line with throw a [`json.exception.type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) + exception if `jd` is not a numerical type, for instance a string. + +The rationale is twofold: + +1. JSON does not define a number type or precision (see [#json-specification](above)). +2. C++ also allows to silently convert between number types. + +!!! success "Conditional number conversion" + + The code above can be solved by explicitly checking the nature of the value with members such as + [`is_number_integer()`](../../api/basic_json/is_number_integer.md) or + [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md): + + ```cpp hl_lines="2" + // check if jd is really integer-valued + if (jd.is_number_integer()) + { + // if so, do the conversion and use i + std::int64_t i = jd.get(); + // ... + } + else + { + // otherwise, take appropriate action + // ... + } + ``` + + Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings. + + (Example taken from [#777](https://github.com/nlohmann/json/issues/777#issuecomment-459968458).) + +### Determine number types + +As the example in [Number conversion](#number-conversion) shows, there are different functions to determine the type of +the stored number: + +- [`is_number()`](../../api/basic_json/is_number.md) returns `#!c true` for any number type +- [`is_number_integer()`](../../api/basic_json/is_number_integer.md) returns `#!c true` for signed and unsigned integers +- [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md) returns `#!c true` for unsigned integers only +- [`is_number_float()`](../../api/basic_json/is_number_float.md) returns `#!c true` for floating-point numbers +- [`type_name()`](../../api/basic_json/type_name.md) returns `#!c "number"` for any number type +- [`type()`](../../api/basic_json/type.md) returns a different enumerator of + [`value_t`](../../api/basic_json/value_t.md) for all number types + +| function | unsigned integer | signed integer | floating-point | string | +|----------------------------------------------------------------------|-------------------|------------------|----------------|----------------| +| [`is_number()`](../../api/basic_json/is_number.md) | `#!c true` | `#!c true` | `#!c true` | `#!c false` | +| [`is_number_integer()`](../../api/basic_json/is_number_integer.md) | `#!c true` | `#!c true` | `#!c false` | `#!c false` | +| [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md) | `#!c true` | `#!c false` | `#!c false` | `#!c false` | +| [`is_number_float()`](../../api/basic_json/is_number_float.md) | `#!c false` | `#!c false` | `#!c true` | `#!c false` | +| [`type_name()`](../../api/basic_json/type_name.md) | `#!c "number"` | `#!c "number"` | `#!c "number"` | `#!c "string"` | +| [`type()`](../../api/basic_json/type.md) | `number_unsigned` | `number_integer` | `number_float` | `string` | + +### Template number types + +The number types can be changed with template parameters. + +| position | number type | default type | possible values | +|----------|-------------------|---------------------|------------------------------------------------| +| 5 | signed integers | `#!c std::int64_t` | `#!c std::int32_t`, `#!c std::int16_t`, etc. | +| 6 | unsigned integers | `#!c std::uint64_t` | `#!c std::uint32_t`, `#!c std::uint16_t`, etc. | +| 7 | floating-point | `#!c double` | `#!c float`, `#!c long double` | + +!!! info "Constraints on number types" + + - The type for signed integers must be convertible from `#!c long long`. The type for floating-point numbers is used + in case of overflow. + - The type for unsigned integers must be convertible from `#!c unsigned long long`. The type for floating-point + numbers is used in case of overflow. + - The types for signed and unsigned integers must be distinct, see + [#2573](https://github.com/nlohmann/json/issues/2573). + - Only `#!c double`, `#!c float`, and `#!c long double` are supported for floating-point numbers. + +!!! example + + A `basic_json` type that uses `#!c long double` as floating-point type. + + ```cpp hl_lines="2" + using json_ld = nlohmann::basic_json; + ``` + + Note values should then be parsed with `json_ld::parse` rather than `json::parse` as the latter would parse + floating-point values to `#!c double` before then converting them to `#!c long double`. diff --git a/json-develop/docs/mkdocs/docs/home/code_of_conduct.md b/json-develop/docs/mkdocs/docs/home/code_of_conduct.md new file mode 100644 index 0000000..770b817 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/code_of_conduct.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/json-develop/docs/mkdocs/docs/home/design_goals.md b/json-develop/docs/mkdocs/docs/home/design_goals.md new file mode 100644 index 0000000..b80551f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/design_goals.md @@ -0,0 +1,17 @@ +# Design goals + +There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals: + +- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples), and you'll know what I mean. + +- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. + +- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289). + +Other aspects were not so important to us: + +- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. + +- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. + +See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. diff --git a/json-develop/docs/mkdocs/docs/home/exceptions.md b/json-develop/docs/mkdocs/docs/home/exceptions.md new file mode 100644 index 0000000..0ecf855 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/exceptions.md @@ -0,0 +1,896 @@ +# Exceptions + +## Overview + +### Base type + +All exceptions inherit from class `json::exception` (which in turn inherits from `std::exception`). It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as "wildcard" to catch exceptions. + +```plantuml +std::exception <|-- json::exception +json::exception <|-- json::parse_error +json::exception <|-- json::invalid_iterator +json::exception <|-- json::type_error +json::exception <|-- json::out_of_range +json::exception <|-- json::other_error + +interface std::exception {} + +class json::exception { + + const int id + + const char* what() const +} + +class json::parse_error { + + const std::size_t byte +} +``` + +### Switch off exceptions + +Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol [`JSON_NOEXCEPTION`](../api/macros/json_noexception.md). In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `#!cpp throw`), `JSON_TRY_USER` (overriding `#!cpp try`), and `JSON_CATCH_USER` (overriding `#!cpp catch`). + +Note that [`JSON_THROW_USER`](../api/macros/json_throw_user.md) should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. + +??? example + + The code below switches off exceptions and creates a log entry with a detailed error message in case of errors. + + ```cpp + #include + + #define JSON_TRY_USER if(true) + #define JSON_CATCH_USER(exception) if(false) + #define JSON_THROW_USER(exception) \ + {std::clog << "Error in " << __FILE__ << ":" << __LINE__ \ + << " (function " << __FUNCTION__ << ") - " \ + << (exception).what() << std::endl; \ + std::abort();} + + #include + ``` + +Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +See [documentation of `JSON_TRY_USER`, `JSON_CATCH_USER` and `JSON_THROW_USER`](../api/macros/json_throw_user.md) for more information. + +### Extended diagnostic messages + +Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult. + +??? example + + ```cpp + --8<-- "examples/diagnostics_standard.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_standard.output" + ``` + + This exception can be hard to debug if storing the value `#!c "12"` and accessing it is further apart. + +To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that lead to the exception) can be created. That global context is provided as [JSON Pointer](../features/json_pointer.md). + +As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) to `1` before including `json.hpp`. + +??? example + + ```cpp + --8<-- "examples/diagnostics_extended.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_extended.output" + ``` + + Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type. + +See [documentation of `JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) for more information. + +## Parse errors + +This exception is thrown by the library when a parse error occurs. Parse errors +can occur during the deserialization of JSON text, CBOR, MessagePack, as well +as when using JSON Patch. + +Exceptions have ids 1xx. + +!!! info "Byte index" + + Member `byte` holds the byte index of the last read character in the input + file. + + For an input with n bytes, 1 is the index of the first character and n+1 + is the index of the terminating null byte or the end of file. This also + holds true when reading a byte vector (CBOR or MessagePack). + +??? example + + The following code shows how a `parse_error` exception can be caught. + + ```cpp + --8<-- "examples/parse_error.cpp" + ``` + + Output: + + ``` + --8<-- "examples/parse_error.output" + ``` + + +### json.exception.parse_error.101 + +This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member `byte` indicates the error position. + +!!! failure "Example message" + + Input ended prematurely: + + ``` + [json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal + ``` + + No input: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal + ``` + + Control character was not escaped: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \u0009 or \\; last read: '"'" + ``` + + String was not closed: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '"' + ``` + + Invalid number format: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E' + ``` + + `\u` was not be followed by four hex digits: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\u' must be followed by 4 hex digits; last read: '"\u01"' + ``` + + Invalid UTF-8 surrogate pair: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '"\uD7FF\uDC00'" + ``` + + Invalid UTF-8 byte: + + ``` + [json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"vous \352t' + ``` + +!!! tip + + - Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened. + - Paste the input to a JSON validator like or a tool like [jq](https://stedolan.github.io/jq/). + +### json.exception.parse_error.102 + +JSON uses the `\uxxxx` format to describe Unicode characters. Code points above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. + +!!! failure "Example message" + + ``` + parse error at 14: missing or wrong low surrogate + ``` + +!!! note + + This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used. + +### json.exception.parse_error.103 + +Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. + +!!! failure "Example message" + + ``` + parse error: code points above 0x10FFFF are invalid + ``` + +!!! note + + This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used. + +### json.exception.parse_error.104 + +[RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.104] parse error: JSON patch must be an array of objects + ``` + +### json.exception.parse_error.105 + +An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.105] parse error: operation 'add' must have member 'value' + ``` + ``` + [json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from' + ``` + ``` + [json.exception.parse_error.105] parse error: operation value 'foo' is invalid + ``` + +### json.exception.parse_error.106 + +An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.106] parse error: array index '01' must not begin with '0' + ``` + +### json.exception.parse_error.107 + +A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo' + ``` + +### json.exception.parse_error.108 + +In a JSON Pointer, only `~0` and `~1` are valid escape sequences. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' + ``` + +### json.exception.parse_error.109 + +A JSON Pointer array index must be a number. + +!!! failure "Example messages" + + ``` + [json.exception.parse_error.109] parse error: array index 'one' is not a number + ``` + ``` + [json.exception.parse_error.109] parse error: array index '+1' is not a number + ``` + +### json.exception.parse_error.110 + +When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input + ``` + ``` + [json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A + ``` + +### json.exception.parse_error.112 + +An unexpected byte was read in a [binary format](../features/binary_formats/index.md) or length information is invalid ([BSON](../features/binary_formats/bson.md)). + +!!! failure "Example messages" + + ``` + [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C + ``` + ``` + [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1 + ``` + +### json.exception.parse_error.113 + +While parsing a map key, a value that is not a string has been read. + +!!! failure "Example messages" + + ``` + [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF + ``` + ``` + [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF + ``` + ``` + [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82 + ``` + +### json.exception.parse_error.114 + +The parsing of the corresponding BSON record type is not implemented (yet). + +!!! failure "Example message" + + ``` + [json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF + ``` + +### json.exception.parse_error.115 + +A UBJSON high-precision number could not be parsed. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A + ``` + +## Iterator errors + +This exception is thrown if iterators passed to a library function do not match +the expected semantics. + +Exceptions have ids 2xx. + +??? example + + The following code shows how an `invalid_iterator` exception can be caught. + + ```cpp + --8<-- "examples/invalid_iterator.cpp" + ``` + + Output: + + ``` + --8<-- "examples/invalid_iterator.output" + ``` + +### json.exception.invalid_iterator.201 + +The iterators passed to constructor `basic_json(InputIT first, InputIT last)` are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.201] iterators are not compatible + ``` + +### json.exception.invalid_iterator.202 + +In the [erase](../api/basic_json/erase.md) or insert function, the passed iterator `pos` does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. + +!!! failure "Example messages" + + ``` + [json.exception.invalid_iterator.202] iterator does not fit current value + ``` + ``` + [json.exception.invalid_iterator.202] iterators first and last must point to objects + ``` + +### json.exception.invalid_iterator.203 + +Either iterator passed to function [`erase(IteratorType first, IteratorType last`)](../api/basic_json/erase.md) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.203] iterators do not fit current value + ``` + +### json.exception.invalid_iterator.204 + +When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an [erase](../api/basic_json/erase.md) function, this range has to be exactly (`begin(),` `end()),` because this is the only way the single stored value is expressed. All other ranges are invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.204] iterators out of range + ``` + +### json.exception.invalid_iterator.205 + +When an iterator for a primitive type (number, boolean, or string) is passed to an [erase](../api/basic_json/erase.md) function, the iterator has to be the `begin()` iterator, because it is the only way to address the stored value. All other iterators are invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.205] iterator out of range + ``` + +### json.exception.invalid_iterator.206 + +The iterators passed to constructor `basic_json(InputIT first, InputIT last)` belong to a JSON null value and hence to not define a valid range. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.206] cannot construct with iterators from null + ``` + +### json.exception.invalid_iterator.207 + +The `key()` member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.207] cannot use key() for non-object iterators + ``` + + +### json.exception.invalid_iterator.208 + +The `operator[]` to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.208] cannot use operator[] for object iterators + ``` + +### json.exception.invalid_iterator.209 + +The offset operators (`+`, `-`, `+=`, `-=`) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.209] cannot use offsets with object iterators + ``` + +### json.exception.invalid_iterator.210 + +The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.210] iterators do not fit + ``` + +### json.exception.invalid_iterator.211 + +The iterator range passed to the insert function must not be a subrange of the container to insert to. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.211] passed iterators may not belong to container + ``` + +### json.exception.invalid_iterator.212 + +When two iterators are compared, they must belong to the same container. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.212] cannot compare iterators of different containers + ``` + +### json.exception.invalid_iterator.213 + +The order of object iterators cannot be compared, because JSON objects are unordered. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.213] cannot compare order of object iterators + ``` + +### json.exception.invalid_iterator.214 + +Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to `begin()`. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.214] cannot get value + ``` + +## Type errors + +This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics. + +Exceptions have ids 3xx. + +??? example + + The following code shows how a `type_error` exception can be caught. + + ```cpp + --8<-- "examples/type_error.cpp" + ``` + + Output: + + ``` + --8<-- "examples/type_error.output" + ``` + +### json.exception.type_error.301 + +To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. + +!!! failure "Example message" + + ``` + [json.exception.type_error.301] cannot create object from initializer list + ``` + +### json.exception.type_error.302 + +During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.302] type must be object, but is null + ``` + ``` + [json.exception.type_error.302] type must be string, but is object + ``` + +### json.exception.type_error.303 + +To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object + ``` + ``` + [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number" + ``` + +### json.exception.type_error.304 + +The `at()` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.304] cannot use at() with string + ``` + ``` + [json.exception.type_error.304] cannot use at() with number + ``` + +### json.exception.type_error.305 + +The `operator[]` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.305] cannot use operator[] with a string argument with array + ``` + ``` + [json.exception.type_error.305] cannot use operator[] with a numeric argument with object + ``` + +### json.exception.type_error.306 + +The `value()` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.306] cannot use value() with number + ``` + +### json.exception.type_error.307 + +The [`erase()`](../api/basic_json/erase.md) member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.307] cannot use erase() with string + ``` + +### json.exception.type_error.308 + +The `push_back()` and `operator+=` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.308] cannot use push_back() with string + ``` + +### json.exception.type_error.309 + +The `insert()` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.309] cannot use insert() with array + ``` + ``` + [json.exception.type_error.309] cannot use insert() with number + ``` + +### json.exception.type_error.310 + +The `swap()` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.310] cannot use swap() with number + ``` + +### json.exception.type_error.311 + +The `emplace()` and `emplace_back()` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.311] cannot use emplace() with number + ``` + ``` + [json.exception.type_error.311] cannot use emplace_back() with number + ``` + +### json.exception.type_error.312 + +The `update()` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.312] cannot use update() with array + ``` + +### json.exception.type_error.313 + +The `unflatten` function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined. + +!!! failure "Example message" + + ``` + [json.exception.type_error.313] invalid value to unflatten + ``` + +### json.exception.type_error.314 + +The `unflatten` function only works for an object whose keys are JSON Pointers. + +!!! failure "Example message" + + Calling `unflatten()` on an array `#!json [1,2,3]`: + + ``` + [json.exception.type_error.314] only objects can be unflattened + ``` + +### json.exception.type_error.315 + +The `unflatten()` function only works for an object whose keys are JSON Pointers and whose values are primitive. + +!!! failure "Example message" + + Calling `unflatten()` on an object `#!json {"/1", [1,2,3]}`: + + ``` + [json.exception.type_error.315] values in object must be primitive + ``` + +### json.exception.type_error.316 + +The `dump()` function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. + +!!! failure "Example message" + + Calling `dump()` on a JSON value containing an ISO 8859-1 encoded string: + ``` + [json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F + ``` + +!!! tip + + - Store the source file with UTF-8 encoding. + - Pass an error handler as last parameter to the `dump()` function to avoid this exception: + - `json::error_handler_t::replace` will replace invalid bytes sequences with `U+FFFD` + - `json::error_handler_t::ignore` will silently ignore invalid byte sequences + +### json.exception.type_error.317 + +The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) + +!!! failure "Example messages" + + Serializing `#!json null` to BSON: + ``` + [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null + ``` + Serializing `#!json [1,2,3]` to BSON: + ``` + [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array + ``` + +!!! tip + + Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}` + +## Out of range + +This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance in case of array indices or nonexisting object keys. + +Exceptions have ids 4xx. + +??? example + + The following code shows how an `out_of_range` exception can be caught. + + ```cpp + --8<-- "examples/out_of_range.cpp" + ``` + + Output: + + ``` + --8<-- "examples/out_of_range.output" + ``` + +### json.exception.out_of_range.401 + +The provided array index `i` is larger than `size-1`. + +!!! failure "Example message" + + ``` + array index 3 is out of range + ``` + +### json.exception.out_of_range.402 + +The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. + +!!! failure "Example message" + + ``` + array index '-' (3) is out of range + ``` + +### json.exception.out_of_range.403 + +The provided key was not found in the JSON object. + +!!! failure "Example message" + + ``` + key 'foo' not found + ``` + +### json.exception.out_of_range.404 + +A reference token in a JSON Pointer could not be resolved. + +!!! failure "Example message" + + ``` + unresolved reference token 'foo' + ``` + +### json.exception.out_of_range.405 + +The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. + +!!! failure "Example message" + + ``` + JSON pointer has no parent + ``` + +### json.exception.out_of_range.406 + +A parsed number could not be stored as without changing it to NaN or INF. + +!!! failure "Example message" + + ``` + number overflow parsing '10E1000' + ``` + +### json.exception.out_of_range.407 + +UBJSON and BSON only support integer numbers up to 9223372036854775807. + +!!! failure "Example message" + + ``` + number overflow serializing '9223372036854775808' + ``` + +!!! note + + Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers, and this exception does not further occur. + +### json.exception.out_of_range.408 + +The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. + +!!! failure "Example message" + + ``` + excessive array size: 8658170730974374167 + ``` + +### json.exception.out_of_range.409 + +Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string. + +!!! failure "Example message" + + ``` + BSON key cannot contain code point U+0000 (at byte 2) + ``` + +## Further exceptions + +This exception is thrown in case of errors that cannot be classified with the +other exception types. + +Exceptions have ids 5xx. + +??? example + + The following code shows how an `other_error` exception can be caught. + + ```cpp + --8<-- "examples/other_error.cpp" + ``` + + Output: + + ``` + --8<-- "examples/other_error.output" + ``` + +### json.exception.other_error.501 + +A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. + +!!! failure "Example message" + + Executing `#!json {"op":"test", "path":"/baz", "value":"bar"}` on `#!json {"baz": "qux"}`: + + ``` + [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"} + ``` diff --git a/json-develop/docs/mkdocs/docs/home/faq.md b/json-develop/docs/mkdocs/docs/home/faq.md new file mode 100644 index 0000000..dd426e0 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/faq.md @@ -0,0 +1,180 @@ +# Frequently Asked Questions (FAQ) + +## Known bugs + +### Brace initialization yields arrays + +!!! question + + Why does + + ```cpp + json j{true}; + ``` + + and + + ```cpp + json j(true); + ``` + + yield different results (`#!json [true]` vs. `#!json true`)? + +This is a known issue, and -- even worse -- the behavior differs between GCC and Clang. The "culprit" for this is the library's constructor overloads for initializer lists to allow syntax like + +```cpp +json array = {1, 2, 3, 4}; +``` + +for arrays and + +```cpp +json object = {{"one", 1}, {"two", 2}}; +``` + +for objects. + +!!! tip + + To avoid any confusion and ensure portable code, **do not** use brace initialization with the types `basic_json`, `json`, or `ordered_json` unless you want to create an object or array as shown in the examples above. + +## Limitations + +### Relaxed parsing + +!!! question + + Can you add an option to ignore trailing commas? + +This library does not support any feature which would jeopardize interoperability. + + +### Parse errors reading non-ASCII characters + +!!! question "Questions" + + - Why is the parser complaining about a Chinese character? + - Does the library support Unicode? + - I get an exception `[json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"Testé$')"` + +The library supports **Unicode input** as follows: + +- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1). +- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers. +- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors. +- [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library. +- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors. +- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs. +- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers. + +In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows where Latin-1 or ISO 8859-1 is often the standard encoding. + + +### Wide string handling + +!!! question + + Why are wide strings (e.g., `std::wstring`) dumped as arrays of numbers? + +As described [above](#parse-errors-reading-non-ascii-characters), the library assumes UTF-8 as encoding. To store a wide string, you need to change the encoding. + +!!! example + + ```cpp + #include // codecvt_utf8 + #include // wstring_convert + + // encoding function + std::string to_utf8(std::wstring& wide_string) + { + static std::wstring_convert> utf8_conv; + return utf8_conv.to_bytes(wide_string); + } + + json j; + std::wstring ws = L"車B1234 こんにちは"; + + j["original"] = ws; + j["encoded"] = to_utf8(ws); + + std::cout << j << std::endl; + ``` + + The result is: + + ```json + { + "encoded": "車B1234 こんにちは", + "original": [36554, 66, 49, 50, 51, 52, 32, 12371, 12435, 12395, 12385, 12399] + } + ``` + +## Exceptions + +### Parsing without exceptions + +!!! question + + Is it possible to indicate a parse error without throwing an exception? + +Yes, see [Parsing and exceptions](../features/parsing/parse_exceptions.md). + + +### Key name in exceptions + +!!! question + + Can I get the key of the object item that caused an exception? + +Yes, you can. Please define the symbol [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) to get [extended diagnostics messages](exceptions.md#extended-diagnostic-messages). + + +## Serialization issues + + +### Number precision + +!!! question + + - It seems that precision is lost when serializing a double. + - Can I change the precision for floating-point serialization? + +The library uses `std::numeric_limits::digits10` (15 for IEEE `double`s) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip. + +!!! quote "[cppreference.com](https://en.cppreference.com/w/cpp/types/numeric_limits/digits10)" + + The value of `std::numeric_limits::digits10` is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow. + +!!! tip + + The website https://float.exposed gives a good insight into the internal storage of floating-point numbers. + +See [this section](../features/types/number_handling.md#number-serialization) on the library's number handling for more information. + +## Compilation issues + +### Android SDK + +!!! question + + Why does the code not compile with Android SDK? + +Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. + +```ini +APP_STL := c++_shared +NDK_TOOLCHAIN_VERSION := clang3.6 +APP_CPPFLAGS += -frtti -fexceptions +``` + +The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10. + + +### Missing STL function + +!!! question "Questions" + + - Why do I get a compilation error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`)? + - Why does the code not compile with MinGW or Android SDK? + +This is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219). diff --git a/json-develop/docs/mkdocs/docs/home/license.md b/json-develop/docs/mkdocs/docs/home/license.md new file mode 100644 index 0000000..baef2f5 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/license.md @@ -0,0 +1,21 @@ +# License + + + +The class is licensed under the [MIT License](https://opensource.org/licenses/MIT): + +Copyright © 2013-2022 [Niels Lohmann](https://nlohmann.me) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +* * * + +The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2008-2009 [Björn Hoehrmann](http://bjoern.hoehrmann.de/) + +The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/) + +The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/json-develop/docs/mkdocs/docs/home/releases.md b/json-develop/docs/mkdocs/docs/home/releases.md new file mode 100644 index 0000000..5237c42 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/releases.md @@ -0,0 +1,1225 @@ +# Releases + +## v3.7.3 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.3/include.zip) (274 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.3/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.3/json.hpp) (791 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.3/json.hpp.asc) (1 KB) + +Release date: 2019-11-17 +SHA-256: 3b5d2b8f8282b80557091514d8ab97e27f9574336c804ee666fda673a9b59926 (json.hpp), 87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014 (include.zip) + +### Summary + +This release fixes a bug introduced in release 3.7.2 which could yield quadratic complexity in destructor calls. All changes are backward-compatible. + +### :bug: Bug Fixes + +- Removed `reserve()` calls from the destructor which could lead to quadratic complexity. #1837 #1838 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + + +## v3.7.2 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.2/include.zip) (274 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.2/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.2/json.hpp) (791 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.2/json.hpp.asc) (1 KB) + +Release date: 2019-11-10 +SHA-256: 0a65fcbbe1b334d3f45c9498e5ee28c3f3b2428aea98557da4a3ff12f0f14ad6 (json.hpp), 67f69c9a93b7fa0612dc1b6273119d2c560317333581845f358aaa68bff8f087 (include.zip) + +### Summary + +Project [bad_json_parsers](https://github.com/lovasoa/bad_json_parsers) tested how JSON parser libraries react on **deeply nested inputs**. It turns out that this library segfaulted at a certain nesting depth. This bug was fixed with this release. **Now the parsing is only bounded by the available memory.** All changes are backward-compatible. + +### :bug: Bug Fixes + +* Fixed a bug that lead to stack overflow for deeply nested JSON values (objects, array) by changing the implementation of the destructor from a recursive to an iterative approach. #832, #1419, #1835 + +### :hammer: Further Changes + +* Added WhiteStone Bolt. #1830 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.7.1 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.1/include.zip) (273 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.1/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.1/json.hpp) (789 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.1/json.hpp.asc) (1 KB) + +Release date: 2019-11-06 +SHA-256: b5ba7228f3c22a882d379e93d08eab4349458ee16fbf45291347994eac7dc7ce (json.hpp), 77b9f54b34e7989e6f402afb516f7ff2830df551c3a36973085e2c7a6b1045fe (include.zip) + +### Summary + +This release fixes several small bugs in the library. All changes are backward-compatible. + +### :bug: Bug Fixes + +- Fixed a segmentation fault when serializing `std::int64_t` minimum value. #1708 #1722 +- Fixed the [`contains()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_ab23b04802eb9da97dc3f664e54e09cb3.html#ab23b04802eb9da97dc3f664e54e09cb3) function for JSON Pointers. #1727 #1741 +- Fixed too lax SFINAE guard for conversion from `std::pair` and `std::tuple` to `json`. #1805 #1806 #1825 #1826 +- Fixed some regressions detected by UBSAN. Updated CI to use Clang-Tidy 7.1.0. #1716 #1728 +- Fixed integer truncation in `iteration_proxy`. #1797 +- Updated [Hedley](https://github.com/nemequ/hedley) to v11 to [fix a E2512 error](https://github.com/nemequ/hedley/issues/28) in MSVC. #1799 +- Fixed a compile error in enum deserialization of non non-default-constructible types. #1647 #1821 +- Fixed the conversion from `json` to `std::valarray`. + +### :zap: Improvements + +- The [`items()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) function can now be used with a custom string type. #1765 +- Made [`json_pointer::back`](https://nlohmann.github.io/json/classnlohmann_1_1json__pointer_a213bc67c32a30c68ac6bf06f5195d482.html#a213bc67c32a30c68ac6bf06f5195d482) `const`. #1764 #1769 +- Meson is part of the release archive. #1672 #1694 +- Improved documentation on the Meson and Spack package manager. #1694 #1720 + +### :hammer: Further Changes + +- Added GitHub Workflow with `ubuntu-latest`/GCC 7.4.0 as CI step. +- Added GCC 9 to Travis CI to compile with C++20 support. #1724 +- Added MSVC 2019 to the AppVeyor CI. #1780 +- Added badge to [fuzzing status](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json). +- Fixed some cppcheck warnings. #1760 +- Fixed several typos in the documentation. #1720 #1767 #1803 +- Added documentation on the `JSON_THROW_USER`, `JSON_TRY_USER`, and `JSON_CATCH_USER` macros to control user-defined exception handling. +- Used GitHub's [CODEOWNERS](https://github.com/nlohmann/json/blob/develop/.github/CODEOWNERS) and [SECURITY](https://github.com/nlohmann/json/blob/develop/.github/SECURITY.md) feature. +- Removed `GLOB` from CMake files. #1779 +- Updated to [Doctest](https://github.com/onqtam/doctest) 2.3.5. + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.7.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.0/include.zip) (143 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.0/json.hpp) (782 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.0/json.hpp.asc) (1 KB) + +Release date: 2019-07-28 +SHA-256: a503214947952b69f0062f572cb74c17582a495767446347ce2e452963fc2ca4 (json.hpp), 541c34438fd54182e9cdc68dd20c898d766713ad6d901fb2c6e28ff1f1e7c10d (include.zip) + +### Summary + +This release introduces a few convenience functions and performs a lot of house keeping (bug fixes and small improvements). All changes are backward-compatible. + +### :sparkles: New Features + +- Add overload of the **[`contains`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab23b04802eb9da97dc3f664e54e09cb3.html#ab23b04802eb9da97dc3f664e54e09cb3) function** to check if a JSON pointer is valid without throwing exceptions, just like its [counterpart for object keys](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9286acdc0578fc66e9346323e69fc0e3.html#a9286acdc0578fc66e9346323e69fc0e3). #1600 +- Add a function **[`to_string`](http://nlohmann.github.io/json/doxygen/namespacenlohmann_a6ce645a0b8717757e096a5b5773b7a16.html#a6ce645a0b8717757e096a5b5773b7a16)** to allow for generic conversion to strings. #916 #1585 +- Add **return value for the [`emplace_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_abf29131f898b05aad2c01a9c80e7a002.html#abf29131f898b05aad2c01a9c80e7a002) function**, returning a reference to the added element just like C++17 is [introducing this](https://en.cppreference.com/w/cpp/container/vector/emplace_back) for `std::vector`. #1609 +- Add info how to use the library with the **[pacman](https://wiki.archlinux.org/index.php/pacman) package manager** on MSYS2. #1670 + +### :bug: Bug Fixes + +- Fix an issue where typedefs with certain names yielded a compilation error. #1642 #1643 +- Fix a conversion to `std::string_view` in the unit tests. #1634 #1639 +- Fix MSVC Debug build. #1536 #1570 #1608 +- Fix [`get_to`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a65753c68f06639eda0d355f919564e01.html#a65753c68f06639eda0d355f919564e01) method to clear existing content before writing. #1511 #1555 +- Fix a `-Wc++17-extensions` warning. `nodiscard` attributes are now only used with Clang when `-std=c++17` is used. #1535 #1551 + +### :zap: Improvements + +- Switch from [Catch](https://github.com/philsquared/Catch) to **[doctest](https://github.com/onqtam/doctest)** for the unit tests which speeds up compilation and runtime of the 112,112,308 tests. +- Add an explicit section to the [README](https://github.com/nlohmann/json/blob/develop/README.md) about the **frequently addressed topics** [character encoding](https://github.com/nlohmann/json#character-encoding), [comments in JSON](https://github.com/nlohmann/json#comments-in-json), and the [order of object keys](https://github.com/nlohmann/json#order-of-object-keys). + +### :hammer: Further Changes + +- Use [`GNUInstallDirs`](https://cmake.org/cmake/help/v3.0/module/GNUInstallDirs.html) to set library install directories. #1673 +- Fix links in the [README](https://github.com/nlohmann/json/blob/develop/README.md). #1620 #1621 #1622 #1623 #1625 +- Mention [`json` type](http://nlohmann.github.io/json/doxygen/namespacenlohmann_a2bfd99e845a2e5cd90aeaf1b1431f474.html#a2bfd99e845a2e5cd90aeaf1b1431f474) on the [documentation start page](http://nlohmann.github.io/json/doxygen/index.html). #1616 +- Complete documentation of [`value()` function](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_adcf8ca5079f5db993820bf50036bf45d.html#adcf8ca5079f5db993820bf50036bf45d) with respect to `type_error.302` exception. #1601 +- Fix links in the documentation. #1598 +- Add regression tests for MSVC. #1543 #1570 +- Use **[CircleCI](http://circleci.com)** for [continuous integration](https://circleci.com/gh/nlohmann/json). +- Use **[Doozer](https://doozer.io)** for [continuous integration](https://doozer.io/nlohmann/json) on Linux (CentOS, Raspbian, Fedora) +- Add tests to check each CMake flag (`JSON_BuildTests`, `JSON_Install`, `JSON_MultipleHeaders`, `JSON_Sanitizer`, `JSON_Valgrind`, `JSON_NoExceptions`, `JSON_Coverage`). +- Use [Hedley](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros like `JSON_DEPRECATED`, `JSON_NODISCARD`, `JSON_LIKELY`, `JSON_UNLIKELY`, `JSON_HAS_CPP_14`, or `JSON_HAS_CPP_17`. Functions taking or returning pointers are annotated accordingly when a pointer will not be null. +- Build and run tests on [AppVeyor](https://ci.appveyor.com/project/nlohmann/json) in DEBUG and RELEASE mode. + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.6.1 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip) (136 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.6.1/json.hpp) (711 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.6.1/json.hpp.asc) (1 KB) + +Release date: 2019-03-20 +SHA-256: d2eeb25d2e95bffeb08ebb7704cdffd2e8fca7113eba9a0b38d60a5c391ea09a (json.hpp), 69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf (include.zip) + +### Summary + +This release **fixes a regression and a bug** introduced by the earlier 3.6.0 release. All changes are backward-compatible. + +### :bug: Bug Fixes + +- Fixed regression of #590 which could lead to compilation errors with GCC 7 and GCC 8. #1530 +- Fixed a compilation error when `` was included. #1531 + +### :hammer: Further Changes + +- Fixed a warning for missing field initializers. #1527 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.6.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.6.0/include.zip) (136 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.6.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.6.0/json.hpp) (711 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.6.0/json.hpp.asc) (1 KB) + +Release date: 2019-03-20 +SHA-256: ce9839370f28094c71107c405affb3b08c4a098154988014cbb0800b1c44a831 (json.hpp), 237c5e66e7f8186a02804ce9dbd5f69ce89fe7424ef84adf6142e973bd9532f4 (include.zip) + +ℹ️ **This release introduced a regression. Please update to [version 3.6.1](https://github.com/nlohmann/json/releases/tag/v3.6.1)!** + +### Summary + +This release adds some **convenience functions for JSON Pointers**, introduces a [`contains`]( +http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a0a45fc740637123fdf05fef970f8be47.html#a0a45fc740637123fdf05fef970f8be47) function to check if a key is present in an object, and improves the **performance of integer serialization**. Furthermore, a lot of small bug fixes and improvements have been made. All changes are backward-compatible. + +### :sparkles: New Features + +- Overworked the public interface for JSON Pointers. The creation of JSON Pointers is simplified with [`operator/`]( +http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a90a11fe6c7f37b1746a3ff9cb24b0d53.html#a90a11fe6c7f37b1746a3ff9cb24b0d53) and [`operator/=`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a7395bd0af29ac23fd3f21543c935cdfa.html#a7395bd0af29ac23fd3f21543c935cdfa). JSON Pointers can be inspected with [`empty`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a649252bda4a2e75a0915b11a25d8bcc3.html#a649252bda4a2e75a0915b11a25d8bcc3), [`back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a6bd5b554c10f15672135c216893eef31.html#a6bd5b554c10f15672135c216893eef31), and [`parent_pointer`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_afdaacce1edb7145e0434e014f0e8685a.html#afdaacce1edb7145e0434e014f0e8685a), and manipulated with [`push_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a697d12b5bd6205f8866691b166b7c7dc.html#a697d12b5bd6205f8866691b166b7c7dc) and [`pop_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a4b1ee4d511ca195bed896a3da47e264c.html#a4b1ee4d511ca195bed896a3da47e264c). #1434 +- Added a boolean method [`contains`]( +http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a0a45fc740637123fdf05fef970f8be47.html#a0a45fc740637123fdf05fef970f8be47) to check whether an element exists in a JSON object with a given key. Returns false when called on non-object types. #1471 #1474 + +### :bug: Bug Fixes + +- Fixed a compilation issues with libc 2.12. #1483 #1514 +- Fixed endian conversion on PPC64. #1489 +- Fixed library to compile with GCC 9. #1472 #1492 +- Fixed a compilation issue with GCC 7 on CentOS. #1496 +- Fixed an integer overflow. #1447 +- Fixed buffer flushing in serializer. #1445 #1446 + +### :zap: Improvements + +- The performance of dumping integers has been greatly improved. #1411 +- Added CMake parameter `JSON_Install` to control whether the library should be installed (default: on). #1330 +- Fixed a lot of compiler and linter warnings. #1400 #1435 #1502 +- Reduced required CMake version from 3.8 to 3.1. #1409 #1428 #1441 #1498 +- Added `nodiscard` attribute to `meta()`, `array()`, `object()`, `from_cbor`, `from_msgpack`, `from_ubjson`, `from_bson`, and `parse`. #1433 + +### :hammer: Further Changes + +- Added missing headers. #1500 +- Fixed typos and broken links in README. #1417 #1423 #1425 #1451 #1455 #1491 +- Fixed documentation of parse function. #1473 +- Suppressed warning that cannot be fixed inside the library. #1401 #1468 +- Imroved package manager suppert: + - Updated Buckaroo instructions. #1495 + - Improved Meson support. #1463 + - Added Conda package manager documentation. #1430 + - Added NuGet package manager documentation. #1132 +- Continuous Integration + - Removed unstable or deprecated Travis builders (Xcode 6.4 - 8.2) and added Xcode 10.1 builder. + - Added Clang 7 to Travis CI. + - Fixed AppVeyor x64 builds. #1374 #1414 +- Updated thirdparty libraries: + - Catch 1.12.0 -> 1.12.2 + - Google Benchmark 1.3.0 -> 1.4.1 + - Doxygen 1.8.15 -> 1.8.16 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.5.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.5.0/include.zip) (133 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.5.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.5.0/json.hpp) (693 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.5.0/json.hpp.asc) (1 KB) + +Release date: 2018-12-22 +SHA-256: 8a6dbf3bf01156f438d0ca7e78c2971bca50eec4ca6f0cf59adf3464c43bb9d5 (json.hpp), 3564da9c5b0cf2e032f97c69baedf10ddbc98030c337d0327a215ea72259ea21 (include.zip) + +### Summary + +This release introduces the support for **structured bindings** and reading from **`FILE*`**. Besides, a few bugs have been fixed. All changes are backward-compatible. + +### :sparkles: New Features + +- **Structured bindings** are now supported for JSON objects and arrays via the [`items()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) member function, so finally this code is possible: + ```cpp + for (auto& [key, val] : j.items()) { + std::cout << key << ':' << val << '\n'; + } + ``` + #1388 #1391 + +- Added support for **reading from `FILE*`** to support situations in which streams are nit available or would require too much RAM. #1370 #1392 + +### :bug: Bug Fixes + +- The `eofbit` was not set for input streams when the end of a stream was reached while parsing. #1340 #1343 +- Fixed a bug in the SAX parser for BSON arrays. + +### :zap: Improvements + +- Added support for Clang 5.0.1 (PS4 version). #1341 #1342 + +### :hammer: Further Changes + +- Added a warning for implicit conversions to the documentation: It is not recommended to use implicit conversions when reading **from** a JSON value. Details about this recommendation can be found [here](https://www.github.com/nlohmann/json/issues/958). #1363 +- Fixed typos in the documentation. #1329 #1380 #1382 +- Fixed a C4800 warning. #1364 +- Fixed a `-Wshadow` warning #1346 +- Wrapped `std::snprintf` calls to avoid error in MSVC. #1337 +- Added code to allow installation via Meson. #1345 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.4.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.4.0/include.zip) (132 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.4.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.4.0/json.hpp) (689 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.4.0/json.hpp.asc) (1 KB) + +Release date: 2018-10-30 +SHA-256: 63da6d1f22b2a7bb9e4ff7d6b255cf691a161ff49532dcc45d398a53e295835f (json.hpp), bfec46fc0cee01c509cf064d2254517e7fa80d1e7647fea37cf81d97c5682bdc (include.zip) + +### Summary + +This release introduces three new features: + +- **BSON (Binary JSON)** is next to CBOR, MessagePack, and UBJSON the fourth binary (de)serialization format supported by the library. +- **Adjustable error handlers for invalid Unicode** allows to specify the behavior when invalid byte sequences are serialized. +- **Simplified enum/JSON mapping** with a macro in case the default mapping to integers is not desired. + +Furthermore, some effort has been invested in improving the **parse error messages**. Besides, a few bugs have been fixed. All changes are backward-compatible. + +### :sparkles: New Features + +- The library can read and write a subset of **[BSON](http://bsonspec.org/) (Binary JSON)**. All data types known from JSON are supported, whereas other types more tied to MongoDB such as timestamps, object ids, or binary data are currently not implemented. See [the README](https://github.com/nlohmann/json#binary-formats-bson-cbor-messagepack-and-ubjson) for examples. #1244 #1320 +- The behavior when the library encounters an invalid Unicode sequence during serialization can now be controlled by defining one of three **Unicode error handlers**: (1) throw an exception (default behavior), (2) replace invalid sequences by the Unicode replacement character (U+FFFD), or (3) ignore/filter invalid sequences. See the [documentation of the `dump` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) for examples. #1198 #1314 +- To easily specify a user-defined **enum/JSON mapping**, a macro `NLOHMANN_JSON_SERIALIZE_ENUM` has been introduced. See the [README section](https://github.com/nlohmann/json#specializing-enum-conversion) for more information. #1208 #1323 + +### :bug: Bug Fixes + +- fixed truncation #1286 #1315 +- fixed an issue with std::pair #1299 #1301 +- fixed an issue with std::variant #1292 #1294 +- fixed a bug in the JSON Pointer parser + +### :zap: Improvements + +- The **diagnosis messages for parse errors** have been improved: error messages now indicated line/column positions where possible (in addition to a byte count) and also the context in which the error occurred (e.g., "while parsing a JSON string"). Example: error `parse error at 2: syntax error - invalid string: control character must be escaped; last read: ''` is now reported as `parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \u0009 or \t; last read: ''`. #1280 #1288 #1303 + +### :hammer: Further Changes + +- improved Meson documentation #1305 +- fixed some more linter warnings #1280 +- fixed Clang detection for third-party Google Benchmark library #1277 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.3.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.3.0/include.zip) (123 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.3.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.3.0/json.hpp) (635 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.3.0/json.hpp.asc) (1 KB) + +Release date: 2018-10-05 +SHA-256: f1327bb60c58757a3dd2b0c9c45d49503d571337681d950ec621f8374bcc14d4 (json.hpp), 9588d63557333aaa485e92221ec38014a85a6134e7486fe3441e0541a5a89576 (include.zip) + +### Summary + +This release adds support for **GCC 4.8**. Furthermore, it adds a function [**`get_to`**](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a8a3db7d78f74232d3a6fb8f1abf69709.html#a8a3db7d78f74232d3a6fb8f1abf69709) to write a JSON value to a passed reference. Another topic of this release was the **CMake support** which has been overworked and documented. + +Besides, a lot of bugs have been fixed and slight improvements have been made. All changes are backward-compatible. + +### :sparkles: New Features + +- The library can now also built with **GCC 4.8**. Though this compiler does not fully support C++11, it can successfully compile and run the test suite. Note that bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824) in GCC 4.8 still forbids to use multiline raw strings in arguments to macros. #1257 +- Added new function [**`get_to`**](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a8a3db7d78f74232d3a6fb8f1abf69709.html#a8a3db7d78f74232d3a6fb8f1abf69709) to write a JSON value to a passed reference. The destination type is automatically derived which allows more succinct code compared to the `get` function. #1227 #1231 + +### :bug: Bug Fixes + +- Fixed a bug in the CMake file that made `target_link_libraries` to not properly include `nlohmann_json`. #1243 #1245 #1260 +- Fixed a warning in MSVC 2017 complaining about a constexpr if. #1204 #1268 #1272 +- Fixed a bug that prevented compilation with ICPC. #755 #1222 +- Improved the SFINAE correctness to fix a bug in the conversion operator. #1237 #1238 +- Fixed a `-Wctor-dtor-privacy` warning. #1224 +- Fixed a warning on a lambda in unevaluated context. #1225 #1230 +- Fixed a bug introduced in version 3.2.0 where defining `JSON_CATCH_USER` led to duplicate macro definition of `JSON_INTERNAL_CATCH`. #1213 #1214 +- Fixed a bug that prevented compilation with Clang 3.4.2 in RHEL 7. #1179 #1249 + +### :zap: Improvements + +- Added [documentation on CMake integration](https://github.com/nlohmann/json#cmake) of the library. #1270 +- Changed the CMake file to use `find_package(nlohmann_json)` without installing the library. #1202 +- Improved error messages in case `operator[]` is used with the wrong combination (json.exception.type_error.305) of JSON container type and argument type. Example: "cannot use operator[] with a string argument". #1220 #1221 +- Added a license and version information to the Meson build file. #1252 +- Removed static assertions to indicated missing `to_json` or `from_json` functions as such assertions do not play well with SFINAE. These assertions also led to problems with GMock. #960 #1212 #1228 +- The test suite now does not wait forever if run in a wrong directory and input files are not found. #1262 +- The test suite does not show deprecation warnings for deprecated functions which frequently led to confusion. #1271 + +### :hammer: Further Changes + +- GCC 4.8 and Xcode 10 were added to the [continuous integration suite](https://travis-ci.org/nlohmann/json) at Travis. +- Added [lgtm](https://lgtm.com/projects/g/nlohmann/json/context:cpp) checks to pull requests. +- Added tests for CMake integration. #1260 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + + +## v3.2.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.2.0/include.zip) (124 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.2.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.2.0/json.hpp) (636 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.2.0/json.hpp.asc) (1 KB) + +Release date: 2018-08-20 +SHA-256: ce6b5610a051ec6795fa11c33854abebb086f0fd67c311f5921c3c07f9531b44 (json.hpp), 35ee642558b90e2f9bc758995c4788c4b4d4dec54eef95fb8f38cb4d49c8fc7c (include.zip) + +### Summary + +This release introduces a [**SAX interface**](https://nlohmann.github.io/json/structnlohmann_1_1json__sax.html) to the library. While this may be a very special feature used by only few people, it allowed to unify all functions that consumed input and created some kind of JSON value. Internally, now all existing functions like `parse`, `accept`, `from_cbor`, `from_msgpack`, and `from_ubjson` use the SAX interface with different event processors. This allowed to separate the input processing from the value generation. Furthermore, throwing an exception in case of a parse error is now optional and up to the event processor. Finally, the JSON parser is now non-recursive (meaning it does not use the call stack, but `std::vector` to track the hierarchy of structured values) which allows to process nested input more efficiently. + +Furthermore, the library finally is able to parse from **wide string types**. This is the first step toward opening the library from UTF-8 to UTF-16 and UTF-32. + +This release further fixes several bugs in the library. All changes are backward-compatible. + +### :sparkles: New Features + +- added a parser with a **SAX interface** (#971, #1153) +- support to parse from **wide string types** `std::wstring`, `std::u16string`, and `std::u32string`; the input will be converted to UTF-8 (#1031) +- added support for **`std::string_view`** when using C++17 (#1028) +- allow to **roundtrip `std::map` and `std::unordered_map`** from JSON if key type is not convertible to string; in these cases, values are serialized to arrays of pairs (#1079, #1089, #1133, #1138) + +### :bug: Bug Fixes + +- allow to create `nullptr_t` from JSON allowing to properly roundtrip `null` values (#1169) +- allow compare user-defined string types (#1130) +- better support for algorithms using iterators from `items()` (#1045, #1134) +- added parameter to avoid compilation error with MSVC 2015 debug builds (#1114) +- re-added accidentally skipped unit tests (#1176) +- fixed MSVC issue with `std::swap` (#1168) + +### :zap: Improvements + +- `key()` function for iterators returns a const reference rather than a string copy (#1098) +- binary formats CBOR, MessagePack, and UBJSON now supports `float` as type for floating-point numbers (#1021) + +### :hammer: Further Changes + +- changed issue templates +- improved continuous integration: added builders for Xcode 9.3 and 9.4, added builders for GCC 8 and Clang 6, added builder for MinGW, added builders for MSVC targeting x86 +- required CMake version is now at least 3.8 (#1040) +- overworked CMake file wrt. packaging (#1048) +- added package managers: Spack (#1041) and CocoaPods (#1148) +- fixed Meson include directory (#1142) +- preprocessor macro `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK` can skip the rejection of unsupported compilers - use at your own risk! (#1128) +- preprocessor macro `JSON_INTERNAL_CATCH`/`JSON_INTERNAL_CATCH_USER` allows to control the behavior of exception handling inside the library (#1187) +- added note on `char` to JSON conversion +- added note how to send security-related issue via encrypted email +- removed dependency to `std::stringstream` (#1117) +- added SPDX-License-Identifier +- added updated JSON Parsing Test Suite, described in [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.php) +- updated to Catch 1.12.0 + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + + + +## v3.1.2 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.1.2/include.zip) (115 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.1.2/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.1.2/json.hpp) (582 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.1.2/json.hpp.asc) (1 KB) + +Release date: 2018-03-14 +SHA-256: fbdfec4b4cf63b3b565d09f87e6c3c183bdd45c5be1864d3fcb338f6f02c1733 (json.hpp), 495362ee1b9d03d9526ba9ccf1b4a9c37691abe3a642ddbced13e5778c16660c (include.zip) + +### Summary + +This release fixes several bugs in the library. All changes are backward-compatible. + +### :bug: Bug Fixes + +- Fixed a **memory leak** occurring in the parser callback (#1001). +- Different **specializations of `basic_json`** (e.g., using different template arguments for strings or objects) can now be used in assignments (#972, #977, #986). +- Fixed a logical error in an iterator range check (#992). + +### :zap: Improvements + +- The parser and the serialization now support **user-defined string types** (#1006, #1009). + +### :hammer: Further Changes + +- **[Clang Analyzer](http://clang-analyzer.llvm.org)** is now used as additional static analyzer; see `make clang_analyze`. +- Overworked [README](https://github.com/nlohmann/json/blob/develop/README.md) by adding links to the [documentation](https://nlohmann.github.io/json/) (#981). + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + + +## v3.1.1 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.1.1/include.zip) (114 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.1.1/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.1.1/json.hpp) (577 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.1.1/json.hpp.asc) (1 KB) + +Release date: 2018-02-13 +SHA-256: e14ce5e33d6a2daf748026bd4947f3d9686ca4cfd53d10c3da46a0a9aceb7f2e (json.hpp), fde771d4b9e4f222965c00758a2bdd627d04fb7b59e09b7f3d1965abdc848505 (include.zip) + +### Summary + +This release fixes several bugs in the library. All changes are backward-compatible. + +### :bug: Bug Fixes + +- Fixed parsing of **CBOR strings with indefinite length** (#961). Earlier versions of this library misinterpreted the CBOR standard and rejected input with the `0x7F` start byte. +- Fixed user-defined **conversion to vector type** (#924, #969). A wrong SFINAE check rejected code though a user-defined conversion was provided. +- Fixed documentation of the parser behavior for **objects with duplicate keys** (#963). The exact behavior is not specified by [RFC 8259](https://tools.ietf.org/html/rfc8259) and the library now also provides no guarantee which object key is stored. +- Added check to detect memory **overflow when parsing UBJSON containers** (#962). The optimized UBJSON format allowed for specifying an array with billions of `null` elements with a few bytes and the library did not check whether this size exceeded `max_size()`. + +### :hammer: Further Changes + +- [Code coverage](https://coveralls.io/github/nlohmann/json) is now calculated for the individual header files, allowing to find uncovered lines more quickly than by browsing through the single header version (#953, #957). +- A Makefile target `run_benchmarks` was added to quickly build and run the benchmark suite. +- The documentation was harmonized with respect to the header inclusion (#955). Now all examples and the README use `#include ` to allow for selecting `single_include` or `include` or whatever installation folder as include directory. +- Added note on how to use the library with the [cget](http://cget.readthedocs.io/en/latest/) package manager (#954). + +### :fire: Deprecated functions + +This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead. +- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.1.0 + +!!! summary "Files" + + - [include.zip](https://github.com/nlohmann/json/releases/download/v3.1.0/include.zip) (114 KB) + - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.1.0/include.zip.asc) (1 KB) + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.1.0/json.hpp) (577 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.1.0/json.hpp.asc) (1 KB) + +Release date: 2018-02-01 +SHA-256: d40f614d10a6e4e4e80dca9463da905285f20e93116c36d97d4dc1aa63d10ba4 (json.hpp), 2b7234fca394d1e27b7e017117ed80b7518fafbb4f4c13a7c069624f6f924673 (include.zip) + +### Summary + +This release adds support for the [**UBJSON**](http://ubjson.org) format and [**JSON Merge Patch**](https://tools.ietf.org/html/rfc7386). It also contains some minor changes and bug fixes. All changes are backward-compatible. + +### :sparkles: New features + +- The library now supports [**UBJSON**](http://ubjson.org) (Universal Binary JSON Specification) as binary format to read and write JSON values space-efficiently. See the [documentation overview](https://github.com/nlohmann/json/blob/develop/doc/binary_formats.md) for a comparison of the different formats CBOR, MessagePack, and UBJSON. +- [**JSON Merge Patch**](https://tools.ietf.org/html/rfc7386) (RFC 7386) offers an intuitive means to describe patches between JSON values (#876, #877). See the documentation of [`merge_patch`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a0ec0cd19cce42ae6071f3cc6870ea295.html#a0ec0cd19cce42ae6071f3cc6870ea295) for more information. + +### :zap: Improvements + +- The library now uses the **Grisu2 algorithm** for printing floating-point numbers (based on the reference implementation by Florian Loitsch) which produces a short representation which is guaranteed to round-trip (#360, #935, #936). +- The **UTF-8 handling** was further simplified by using the decoder of Björn Hoehrmann in more scenarios. + +### :truck: Reorganization + +- Though the library is released as a single header, its development got more and more complicated. With this release, the header is **split into several files** and the single-header file `json.hpp` can be generated from these development sources. In the repository, folder `include` contains the development sources and `single_include` contains the single `json.hpp` header (#700, #906, #907, #910, #911, #915, #920, #924, #925, #928, #944). +- The split further allowed for a **forward declaration header** `include/nlohmann/json_fwd.hpp` to speed up compilation times (#314). + +### :hammer: Further changes + +- [Google Benchmark](https://github.com/google/benchmark) is now used for micro benchmarks (see `benchmarks` folder, #921). +- The serialization (JSON and binary formats) now properly work with the libraries string template parameter, allowing for optimized string implementations to be used in constraint environments such as embedded software (#941, #950). +- The exceptional behavior can now be overridden by defining macros `JSON_THROW_USER`, `JSON_TRY_USER`, and `JSON_CATCH_USER`, defining the behavior of `throw`, `try` and `catch`, respectively. This allows to switch off C++'s exception mechanism yet still execute user-defined code in case an error condition occurs (#938). +- To facilitate the interplay with [flex](https://github.com/westes/flex) and [Bison](https://www.gnu.org/software/bison/), the library does not use the variable name `yytext` any more as it could clash with macro definitions (#933). +- The library now defines `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and `NLOHMANN_JSON_VERSION_PATCH` to allow for conditional compilation based on the included library version (#943, #948). +- A compilation error with ICC has been fixed (#947). +- Typos and links in the documentation have been fixed (#900, #930). +- A compiler error related to incomplete types has been fixed (#919). +- The tests form the [UTF-8 decoder stress test](http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt) have been added to the test suite. + +### :fire: Deprecated functions + +- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) has been deprecated (#874). Since its introduction, the name was up for discussion, as it was too technical. We now introduced the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) with the same semantics. `iterator_wrapper` will be removed in the next major version (i.e., 4.0.0). + +Furthermore, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0): + +- [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) +- [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) + +Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.0.1 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.0.1/json.hpp) (502 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.0.1/json.hpp.asc) (1 KB) + +Release date: 2017-12-29 +SHA-256: c9b3591f1bb94e723a0cd7be861733a3a555b234ef132be1e9027a0364118c4c + +### Summary + +This release fixes small issues in the implementation of **JSON Pointer** and **JSON Patch**. All changes are backward-compatible. + +### Changes + +- :bug: The **"copy" operation of JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) requests that it is an error if the target path points into a non-existing array or object (see #894 for a detailed description). This release fixes the implementation to detect such invalid target paths and throw an exception. +- :bug: An **array index in a JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) must be an integer. This release fixes the implementation to throw an exception in case invalid array indices such as `10e2` are used. +- :white_check_mark: Added the [JSON Patch tests](https://github.com/json-patch/json-patch-tests) from Byron Ruth and Mike McCabe. +- :memo: Fixed the documentation of the [`at(ptr)` function with JSON Pointers](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a8ab61397c10f18b305520da7073b2b45.html#a8ab61397c10f18b305520da7073b2b45) to list all possible exceptions (see #888). +- :memo: Updated the [container overview documentation](https://nlohmann.github.io/json/) (see #883). +- :wrench: The CMake files now respect the [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/module/CTest.html?highlight=build_testing) option (see #846, #885) +- :rotating_light: Fixed some compiler warnings (see #858, #882). + +### Deprecated functions + +:fire: To unify the interfaces and to improve similarity with the STL, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0): + +- [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) +- [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) + +Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +## v3.0.0 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.0.0/json.hpp) (501 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.0.0/json.hpp.asc) (1 KB) + +Release date: 2017-12-17 +SHA-256: 076d4a0cb890a3c3d389c68421a11c3d77c64bd788e85d50f1b77ed252f2a462 + +### Summary + + + +After almost a year, here is finally a new release of JSON for Modern C++, and it is a major one! As we adhere to [semantic versioning](https://semver.org), this means the release includes some breaking changes, so please read the next section carefully before you update. But don't worry, we also added a few new features and put a lot of effort into fixing a lot of bugs and straighten out a few inconsistencies. + +### :boom: Breaking changes + +This section describes changes that change the public API of the library and may require changes in code using a previous version of the library. In section "Moving from 2.x.x to 3.0.0" at the end of the release notes, we describe in detail how existing code needs to be changed. + +- The library now uses [**user-defined exceptions**](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9a0aced019cb1d65bb49703406c84970.html#a9a0aced019cb1d65bb49703406c84970) instead of re-using those defined in `` (#244). This not only allows to add more information to the exceptions (every exception now has an identifier, and parse errors contain the position of the error), but also to easily catch all library exceptions with a single `catch(json::exception)`. +- When strings with a different encoding as UTF-8 were stored in JSON values, their serialization could not be parsed by the library itself, as only UTF-8 is supported. To enforce this library limitation and improve consistency, **non-UTF-8 encoded strings now yield a `json::type_error` exception during serialization** (#838). The check for valid UTF-8 is realized with code from [Björn Hoehrmann](http://bjoern.hoehrmann.de/). +- **NaN and infinity values can now be stored inside the JSON value** without throwing an exception. They are, however, still serialized as `null` (#388). +- The library's iterator tag was changed from RandomAccessIterator to **[BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator)** (#593). Supporting RandomAccessIterator was incorrect as it assumed an ordering of values in a JSON objects which are unordered by definition. +- The library does not include the standard headers ``, ``, and `` any more. You may need to add these headers to code relying on them. +- Removed constructor `explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)` which was deprecated in version 2.0.0 (#480). + +### :fire: Deprecated functions + +To unify the interfaces and to improve similarity with the STL, the following functions are now deprecated and will be removed in the next major version (i.e., 4.0.0): + +- [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) +- [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) + +Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead. + +### :sparkles: New features + +With all this breaking and deprecation out of the way, let's talk about features! + +- We improved the **diagnostic information for syntax errors** (#301). Now, an exception [`json::parse_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1efc2468e6022be6e35fc2944cabe4d.html#af1efc2468e6022be6e35fc2944cabe4d) is thrown which contains a detailed message on the error, but also a member `byte` to indicate the byte offset in the input where the error occurred. +- We added a **non-throwing syntax check** (#458): The new `accept` function returns a Boolean indicating whether the input is proper JSON. We also added a Boolean parameter `allow_exceptions` to the existing [`parse`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aa9676414f2e36383c4b181fe856aa3c0.html#aa9676414f2e36383c4b181fe856aa3c0) functions to return a `discarded` value in case a syntax error occurs instead of throwing an exception. +- An [`update`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a1cfa9ae5e7c2434cab4cfe69bffffe11.html#a1cfa9ae5e7c2434cab4cfe69bffffe11) function was added to **merge two JSON objects** (#428). In case you are wondering: the name was inspired by [Python](https://docs.python.org/2/library/stdtypes.html#dict.update). +- The [`insert`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a1b0a4e60d56f1fe80501ed941e122892.html#a1b0a4e60d56f1fe80501ed941e122892) function now also supports an iterator range to add elements to an object. +- The binary exchange formats **CBOR and MessagePack can now be parsed from input streams and written to output streams** (#477). +- Input streams are now only read until the end of a JSON value instead of the end of the input (#367). +- The serialization function [`dump`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5adea76fedba9898d404fef8598aa663.html#a5adea76fedba9898d404fef8598aa663) now has two optional parameters `ensure_ascii` to **escape all non-ASCII characters** with `\uxxxx` and an `indent_char` parameter to choose whether to **indent with spaces or tabs** (#654). +- Added **built-in type support** for C arrays (#502), `std::pair` and `std::tuple` (#563, #614), `enum` and `enum class` (#545), `std::vector` (#494). Fixed support for `std::valarray` (#702), `std::array` (#553), and `std::map` (#600, #607). + +### :hammer: Further changes + +Furthermore, there have been a lot of changes under the hood: + +- Replaced the [re2c](http://re2c.org) generated scanner by a self-coded version which allows for a better modularization of the parser and better diagnostics. To test the new scanner, we added millions (8,860,608 to be exact) of unit tests to check all valid and invalid byte sequences of the Unicode standard. +- Google's OSS-Fuzz is still constantly fuzz-testing the library and found several issues that were fixed in this release (#497, #504, #514, #516, #518, #519, #575). +- We now also ignore UTF-8 byte order marks when parsing from an iterator range (#602). +- Values can be now moved from initializer lists (#663). +- Updated to [Catch](https://github.com/catchorg/Catch2) 1.9.7. Unfortunately, Catch2 currently has some performance issues. +- The non-exceptional paths of the library are now annotated with `__builtin_expect` to optimize branch prediction as long as no error occurs. +- MSVC now produces a stack trace in MSVC if a `from_json` or `to_json` function was not found for a user-defined type. We also added a debug visualizer [`nlohmann_json.natvis`](https://github.com/nlohmann/json/blob/develop/nlohmann_json.natvis) for better debugging in MSVC (#844). +- Overworked the documentation and added even more examples. +- The build workflow now relies on CMake and CTest. Special flags can be chosen with CMake, including coverage (`JSON_Coverage`), compilation without exceptions (`JSON_NoExceptions`), LLVM sanitizers (`JSON_Sanitizer`), or execution with Valgrind (`JSON_Valgrind`). +- Added support for package managers Meson (#576), Conan (#566), Hunter (#671, #829), and vcpkg (#753). +- Added CI builders: Xcode 8.3, 9.0, 9.1, and 9.2; GCC 7.2; Clang 3.8, 3.9, 4.0, and 5.0; Visual Studio 2017. The library is further built with C++17 settings on the latest Clang, GCC, and MSVC version to quickly detect new issues. + +### Moving from 2.x.x to 3.0.0 + +#### User-defined Exceptions + +There are five different exceptions inheriting from [`json::exception`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9a0aced019cb1d65bb49703406c84970.html#a9a0aced019cb1d65bb49703406c84970): + +- [`json::parse_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1efc2468e6022be6e35fc2944cabe4d.html#af1efc2468e6022be6e35fc2944cabe4d) for syntax errors (including the binary formats), +- [`json::invalid_iterator`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ac13d32f7cbd02d616e71d8dc30dadcbf.html#ac13d32f7cbd02d616e71d8dc30dadcbf) for errors related to iterators, +- [`json::type_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a4010e8e268fefd86da773c10318f2902.html#a4010e8e268fefd86da773c10318f2902) for errors where functions were called with the wrong JSON type, +- [`json::out_of_range`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a28f7c2f087274a0012eb7a2333ee1580.html#a28f7c2f087274a0012eb7a2333ee1580) for range errors, and +- [`json::other_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a3333a5a8714912adda33a35b369f7b3d.html#a3333a5a8714912adda33a35b369f7b3d) for miscellaneous errors. + +To support these exception, the `try`/`catch` blocks of your code need to be adjusted: + +| new exception | previous exception | +|:--|:--| +| parse_error.101 | invalid_argument | +| parse_error.102 | invalid_argument | +| parse_error.103 | invalid_argument | +| parse_error.104 | invalid_argument | +| parse_error.105 | invalid_argument | +| parse_error.106 | domain_error | +| parse_error.107 | domain_error | +| parse_error.108 | domain_error | +| parse_error.109 | invalid_argument | +| parse_error.110 | out_of_range | +| parse_error.111 | invalid_argument | +| parse_error.112 | invalid_argument | +| invalid_iterator.201 | domain_error | +| invalid_iterator.202 | domain_error | +| invalid_iterator.203 | domain_error | +| invalid_iterator.204 | out_of_range | +| invalid_iterator.205 | out_of_range | +| invalid_iterator.206 | domain_error | +| invalid_iterator.207 | domain_error | +| invalid_iterator.208 | domain_error | +| invalid_iterator.209 | domain_error | +| invalid_iterator.210 | domain_error | +| invalid_iterator.211 | domain_error | +| invalid_iterator.212 | domain_error | +| invalid_iterator.213 | domain_error | +| invalid_iterator.214 | out_of_range | +| type_error.301 | domain_error | +| type_error.302 | domain_error | +| type_error.303 | domain_error | +| type_error.304 | domain_error | +| type_error.305 | domain_error | +| type_error.306 | domain_error | +| type_error.307 | domain_error | +| type_error.308 | domain_error | +| type_error.309 | domain_error | +| type_error.310 | domain_error | +| type_error.311 | domain_error | +| type_error.313 | domain_error | +| type_error.314 | domain_error | +| type_error.315 | domain_error | +| out_of_range.401 | out_of_range | +| out_of_range.402 | out_of_range | +| out_of_range.403 | out_of_range | +| out_of_range.404 | out_of_range | +| out_of_range.405 | domain_error | +| other_error.501 | domain_error | + +#### Handling of NaN and INF + +- If an overflow occurs during parsing a number from a JSON text, an exception [`json::out_of_range`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a28f7c2f087274a0012eb7a2333ee1580.html#a28f7c2f087274a0012eb7a2333ee1580) is thrown so that the overflow is detected early and roundtripping is guaranteed. + +- NaN and INF floating-point values can be stored in a JSON value and are not replaced by null. That is, the basic_json class behaves like `double` in this regard (no exception occurs). However, NaN and INF are serialized to `null`. + +#### Removal of deprecated functions + +Function `explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)` should be replaced by the `parse` function: Let `ss` be a stream and `cb` be a parse callback function. + +Old code: + +```cpp +json j(ss, cb); +``` + +New code: + +```cpp +json j = json::parse(ss, cb); +``` + +If no callback function is used, also the following code works: + +```cpp +json j; +j << ss; +``` + +or + +```cpp +json j; +ss >> j; +``` + +## v2.1.1 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.1.1/json.hpp) (437 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.1.1/json.hpp.asc) (1 KB) + +Release date: 2017-02-25 +SHA-256: faa2321beb1aa7416d035e7417fcfa59692ac3d8c202728f9bcc302e2d558f57 + +### Summary + +This release **fixes a locale-related bug in the parser**. To do so, the whole number handling (lexer, parser, and also the serialization) have been overworked. Furthermore, a lot of small changes added up that were added to this release. All changes are backward-compatible. + +### Changes +- :bug: Locales that have a different character than `.` as decimal separator (e.g., the Norwegian locale `nb_NO.UTF-8`) led to truncated number parsing or parse errors. The library now has been fixed to work with **any locale**. Note that `.` is still the only valid decimal separator for JSON input. +- :bug: Numbers like `1.0` were correctly parsed as floating-point number, but serialized as integer (`1`). Now, **floating-point numbers correctly round trip**. +- :bug: Parsing incorrect JSON numbers with leading 0 (`0123`) could yield a [buffer overflow](https://github.com/nlohmann/json/issues/452). This is fixed now by detecting such errors directly by the lexer. +- :bug: Constructing a JSON value from a pointer was incorrectly interpreted as a Boolean; such code will now yield a compiler error. +- :bug: Comparing a JSON number with `0` led to a comparison with `null`. This is fixed now. +- :bug: All throw calls are now wrapped in macros. +- :lock: Starting during the preparation of this release (since 8 February 2017), commits and released files are **cryptographically signed** with [this GPG key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69). Previous releases have also been signed. +- :sparkles: The parser for MessagePack and CBOR now supports an optional start index parameter to define a byte offset for the parser. +- :rotating_light: Some more warnings have been fixed. With Clang, the code compiles **without warnings** with `-Weverything` (well, it needs `-Wno-documentation-unknown-command` and `-Wno-deprecated-declarations`, but you get the point). +- :hammer: The code can be compiled easier with many Android NDKs by avoiding macros like `UINT8_MAX` which previously required defining a preprocessor macro for compilation. +- :zap: The unit tests now compile two times faster. +- :heavy_plus_sign: [Cotire](https://github.com/sakra/cotire) is used to speed up the build. +- :pencil2: Fixed a lot of typos in the documentation. +- :memo: Added a section to the README file that lists all used [third-party code/tools](https://github.com/nlohmann/json#used-third-party-tools). +- :memo: Added a note on constructing a string value vs. parsing. +- :white_check_mark: The test suite now contains 11202597 unit tests. +- :memo: Improved the [Doxygen documentation](https://nlohmann.github.io/json/) by shortening the template parameters of class `basic_json`. +- :construction_worker: Removed Doozer. +- :construction_worker: Added Codacity. +- :arrow_up: Upgraded Catch to version 1.7.2. + + +## v2.1.0 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.1.0/json.hpp) (426 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.1.0/json.hpp.asc) (1 KB) + +- Release date: 2017-01-28 +- SHA-256: a571dee92515b685784fd527e38405cf3f5e13e96edbfe3f03d6df2e363a767b + +### Summary + +This release introduces a means to convert from/to user-defined types. The release is backwards compatible. + +![conversion](https://cloud.githubusercontent.com/assets/159488/22399173/aebe8f7a-e597-11e6-930f-7494ee615827.png) + +### Changes +- :sparkles: The library now offers an elegant way to **convert from and to arbitrary value types**. All you need to do is to implement two functions: `to_json` and `from_json`. Then, a conversion is as simple as putting a `=` between variables. See the [README](https://github.com/nlohmann/json#arbitrary-types-conversions) for more information and examples. +- :sparkles: **Exceptions can now be switched off.** This can be done by defining the preprocessor symbol `JSON_NOEXCEPTION` or by passing `-fno-exceptions` to your compiler. In case the code would usually thrown an exception, `abort()` is now called. +- :sparkles: **Information on the library** can be queried with the new (static) function `meta()` which returns a JSON object with information on the version, compiler, and platform. See the [documentation]() for an example. +- :bug: A bug in the CBOR parser was fixed which led to a buffer overflow. +- :sparkles: The function [`type_name()`]() is now public. It allows to query the type of a JSON value as string. +- :white_check_mark: Added the [Big List of Naughty Strings](https://github.com/minimaxir/big-list-of-naughty-strings) as test case. +- :arrow_up: Updated to [Catch v1.6.0](https://github.com/philsquared/Catch/releases/tag/v1.6.0). +- :memo: Some typos in the documentation have been fixed. + + +## v2.0.10 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.10/json.hpp) (409 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.10/json.hpp.asc) (1 KB) + +- Release date: 2017-01-02 +- SHA-256: ec27d4e74e9ce0f78066389a70724afd07f10761009322dc020656704ad5296d + +### Summary + +This release fixes several security-relevant bugs in the MessagePack and CBOR parsers. The fixes are backwards compatible. + +### Changes +- :bug: Fixed a lot of **bugs in the CBOR and MesssagePack parsers**. These bugs occurred if invalid input was parsed and then could lead in buffer overflows. These bugs were found with Google's [OSS-Fuzz](https://github.com/google/oss-fuzz), see #405, #407, #408, #409, #411, and #412 for more information. +- :construction_worker: We now also use the **[Doozer](https://doozer.io) continuous integration platform**. +- :construction_worker: The complete test suite is now also run with **Clang's address sanitizer and undefined-behavior sanitizer**. +- :white_check_mark: Overworked **fuzz testing**; CBOR and MessagePack implementations are now fuzz-tested. Furthermore, all fuzz tests now include a round trip which ensures created output can again be properly parsed and yields the same JSON value. +- :memo: Clarified documentation of `find()` function to always return `end()` when called on non-object value types. +- :hammer: Moved thirdparty test code to `test/thirdparty` directory. + +## v2.0.9 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.9/json.hpp) (406 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.9/json.hpp.asc) (1 KB) + +- Release date: 2016-12-16 +- SHA-256: fbf3396f13e187d6c214c297bddc742d918ea9b55e10bfb3d9f458b9bfdc22e5 + +### Summary + +This release implements with **[CBOR](http://cbor.io)** and **[MessagePack](http://msgpack.org)** two **binary serialization/deserialization formats**. It further contains some small fixes and improvements. The fixes are backwards compatible. + +![cbor](https://cloud.githubusercontent.com/assets/159488/22399181/d4d60d32-e597-11e6-8dcb-825abcf9ac2a.png) + +### Changes +- :sparkles: The library can now read and write the binary formats **[CBOR](http://cbor.io)** (Concise Binary Object Representation) and **[MessagePack](http://msgpack.org)**. Both formats are aimed to produce a very compact representation of JSON which can be parsed very efficiently. See the [README file](https://github.com/nlohmann/json#binary-formats-cbor-and-messagepack) for more information and examples. +- :fire: simplified the iteration implementation allowing to remove dozens of lines of code +- :bug: fixed an [integer overflow error](https://github.com/nlohmann/json/issues/389) detected by [Google's OSS-Fuzz](https://github.com/google/oss-fuzz) +- :bug: suppressed documentation warnings inside the library to facilitate compilation with `-Wdocumentation` +- :bug: fixed an overflow detection error in the number parser +- :memo: updated [contribution guidelines](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md) to a list of frequentely asked features that will most likely be never added to the library +- :memo: added a **table of contents** to the [README file](https://github.com/nlohmann/json/blob/develop/README.md) to add some structure +- :memo: mentioned the many [examples](https://github.com/nlohmann/json/tree/develop/doc/examples) and the [documentation](https://nlohmann.github.io/json/) in the [README file]() +- :hammer: split [unit tests](https://github.com/nlohmann/json/tree/develop/test/src) into individual independent binaries to speed up compilation and testing +- :white_check_mark: the test suite now contains **11201886** tests + +## v2.0.8 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.8/json.hpp) (360 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.8/json.hpp.asc) (1 KB) + +- Release date: 2016-12-02 +- SHA-256: b70db0ad34f8e0e61dc3f0cbab88099336c9674c193d8a3439d93d6aca2d7120 + +### Summary + +This release combines a lot of small fixes and improvements. The fixes are backwards compatible. + +### Changes +- :bug: fixed a bug that froze the parser if a passed file was not found (now, `std::invalid_argument` is thrown) +- :bug: fixed a bug that lead to an error of a file at EOF was parsed again (now, `std::invalid_argument` is thrown) +- :sparkles: the well known functions [`emplace`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a602f275f0359ab181221384989810604.html#a602f275f0359ab181221384989810604) and [`emplace_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af8a435033327d9237da414afc1cce513.html#af8a435033327d9237da414afc1cce513) have been added to JSON values and work as expected +- :zap: improved the performance of the serialization (`dump` function) +- :zap: improved the performance of the deserialization (parser) +- :construction_worker: some continuous integration images at [Travis](https://travis-ci.org/nlohmann/json) were added and retired; see [here](https://github.com/nlohmann/json#supported-compilers) for the current continuous integration setup +- :construction_worker: the [Coverity scan](https://scan.coverity.com/projects/nlohmann-json) works again +- :chart_with_upwards_trend: the benchmarking code has been improved to produce more stable results +- :memo: the [README](https://github.com/nlohmann/json/blob/develop/README.md) file has been extended and includes more frequently asked examples +- :white_check_mark: the test suite now contains 8905518 tests +- :arrow_up: updated [Catch](https://github.com/philsquared/Catch) to version 1.5.8 + +## v2.0.7 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.7/json.hpp) (355 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.7/json.hpp.asc) (1 KB) + +- Release date: 2016-11-02 +- SHA-256: 5545c323670f8165bae90b9dc6078825e86ec310d96cc4e5b47233ea43715bbf + +### Summary + +This release fixes a few bugs in the JSON parser found in the [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.html) article. The fixes are backwards compatible. + +### Changes +- The article [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.html) discusses a lot of pitfalls of the JSON specification. When investigating the published test cases, a few bugs in the library were found and fixed: + - Files with less than 5 bytes can now be parsed without error. + - The library now properly rejects any file encoding other than UTF-8. Furthermore, incorrect surrogate pairs are properly detected and rejected. + - The library now accepts all but one "yes" test (y_string_utf16.json): UTF-16 is not supported. + - The library rejects all but one "no" test (n_number_then_00.json): Null bytes are treated as end of file instead of an error. This allows to parse input from null-terminated strings. +- The string length passed to a user-defined string literal is now exploited to choose a more efficient constructor. +- A few grammar mistakes in the README file have been fixed. + +## v2.0.6 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.6/json.hpp) (349 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.6/json.hpp.asc) (1 KB) + +- Release date: 2016-10-15 +- SHA256: 459cc93d5e2f503e50c6d5876eb86bfea7daf405f5a567c5a2c9abc2383756ae + +### Summary + +This release fixes the semantics of `operator[]` for JSON Pointers (see below). This fix is backwards compatible. + +### Changes +- **`operator[]` for JSON Pointers** now behaves like the other versions of `operator[]` and transforms `null` values into objects or arrays if required. This allows to created nested structures like `j["/foo/bar/2"] = 17` (yielding `{"foo": "bar": [null, null, 17]}`) without problems. +- overworked a helper SFINAE function +- fixed some documentation issues +- fixed the CMake files to allow to run the test suite outside the main project directory +- restored test coverage to 100%. + +## v2.0.5 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.5/json.hpp) (347 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.5/json.hpp.asc) (1 KB) + +- Release date: 2016-09-14 +- SHA-256: 8b7565263a44e2b7d3b89808bc73d2d639037ff0c1f379e3d56dbd77e00b98d9 + +### Summary + +This release fixes a regression bug in the stream parser (function `parse()` and the `<<`/`>>` operators). This fix is backwards compatible. + +### Changes +- **Bug fix**: The end of a file stream was not detected properly which led to parse errors. This bug should have been fixed with 2.0.4, but there was still a flaw in the code. + +## v2.0.4 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.4/json.hpp) (347 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.4/json.hpp.asc) (1 KB) + +- Release date: 2016-09-11 +- SHA-256: 632ceec4c25c4e2153f71470d3a2b992c8355f6d8b4d627d05dd16095cd3aeda + +### Summary + +This release fixes a bug in the stream parser (function `parse()` and the `<<`/`>>` operators). This fix is backwards compatible. + +### Changes +- **Bug fix**: The end of a file stream was not detected properly which led to parse errors. +- Fixed a compiler warning about an unused variable. + +## v2.0.3 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.3/json.hpp) (347 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.3/json.hpp.asc) (1 KB) + +- Release date: 2016-08-31 +- SHA-256: 535b73efe5546fde9e763c14aeadfc7b58183c0b3cd43c29741025aba6cf6bd3 + +### Summary + +This release combines a lot of small fixes and improvements. The release is backwards compatible. + +### Changes +- The **parser/deserialization functions have been generalized** to process any contiguous sequence of 1-byte elements (e.g., `char`, `unsigned char`, `uint8_t`). This includes all kind of string representations (string literals, char arrays, `std::string`, `const char*`), contiguous containers (C-style arrays, `std::vector`, `std::array`, `std::valarray`, `std::initializer_list`). User-defined containers providing random-access iterator access via `std::begin` and `std::end` can be used as well. See the documentation ([1](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_ace63ac4eb1dd7251a259d32e397461a3.html#ace63ac4eb1dd7251a259d32e397461a3), [2](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a90f05d55d9d0702c075cd281fd0d85ae.html#a90f05d55d9d0702c075cd281fd0d85ae), [3](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aeffd70f622f8f2a51fd3d95af64b63a7.html#aeffd70f622f8f2a51fd3d95af64b63a7), [4](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa8dca2e91a6301c36890f844e64f0023.html#aa8dca2e91a6301c36890f844e64f0023)) for more information. Note that contiguous storage cannot be checked at compile time; if any of the parse functions are called with a noncompliant container, the behavior is undefined and will most likely yield segmentation violation. The preconditions are enforced by an assertion unless the library is compiled with preprocessor symbol `NDEBUG`. +- As a general remark on **assertions**: The library uses assertions to preclude undefined behavior. A [prominent example](https://github.com/nlohmann/json/issues/289) for this is the `operator[]` for const JSON objects. The behavior of this const version of the operator is undefined if the given key does not exist in the JSON object, because unlike the non-const version, it cannot add a `null` value at the given key. Assertions can be switched of by defining the preprocessor symbol `NDEBUG`. See the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert) for more information. +- In the course of cleaning up the parser/deserialization functions, the constructor [`basic_json(std::istream&, const parser_callback_t)`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a32350263eb105764844c5a85e156a255.html#a32350263eb105764844c5a85e156a255) has been **deprecated** and will be deleted with the next major release 3.0.0 to unify the interface of the library. Deserialization will be done by stream operators or by calling one of the `parse` functions. That is, calls like `json j(i);` for an input stream `i` need to be replaced by `json j = json::parse(i);`. Compilers will produce a deprecation warning if client code uses this function. +- Minor improvements: + - Improved the performance of the serialization by avoiding the re-creation of a locale object. + - Fixed two MSVC warnings. Compiling the test suite with `/Wall` now only warns about non-inlined functions (C4710) and the deprecation of the constructor from input-stream (C4996). +- Some project internals: + - The project has qualified for the [Core Infrastructure Initiative Best Practices Badge](https://bestpractices.coreinfrastructure.org/projects/289). While most requirements where already satisfied, some led to a more explicit documentation of quality-ensuring procedures. For instance, static analysis is now executed with every commit on the build server. Furthermore, the [contribution guidelines document](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md) how to communicate security issues privately. + - The test suite has been overworked and split into several files to allow for faster compilation and analysis. The execute the test suite, simply execute `make check`. + - The continuous integration with [Travis](https://travis-ci.org/nlohmann/json) was extended with Clang versions 3.6.0 to 3.8.1 and now includes 18 different compiler/OS combinations. + - An 11-day run of [American fuzzy lop](http://lcamtuf.coredump.cx/afl/) checked 962 million inputs on the parser and found no issue. + +## v2.0.2 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.2/json.hpp) (338 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.2/json.hpp.asc) (1 KB) + +- Release date: 2016-07-31 +- SHA-256: 8e97b7965b4594b00998d6704465412360e1a0ed927badb51ded8b82291a8f3d + +### Summary + +This release combines a lot of small fixes and improvements. The release is backwards compatible. + +### Changes +- The **parser** has been overworked, and a lot of small issues have been fixed: + - Improved parser performance by avoiding recursion and using move semantics for the return value. + - Unescaped control characters `\x10`-`\x1f` are not accepted any more. + - Fixed a bug in the parser when reading from an input stream. + - Improved test case coverage for UTF-8 parsing: now, all valid Unicode code points are tested both escaped and unescaped. + - The precision of output streams is now preserved by the parser. +- Started to check the **code correctness** by proving termination of important loops. Furthermore, individual assertions have been replaced by a more systematic function which checks the class invariants. Note that assertions should be switched off in production by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert). +- A lot of **code cleanup**: removed unused headers, fixed some compiler warnings, and fixed a build error for Windows-based Clang builds. +- Added some compile-time checks: + - Unsupported compilers are rejected during compilation with an `#error` command. + - Static assertion prohibits code with incompatible pointer types used in `get_ptr()`. +- Improved the [documentation](https://nlohmann.github.io/json/), and adjusted the documentation script to choose the correct version of `sed`. +- Replaced a lot of "raw loops" by STL functions like `std::all_of`, `std::for_each`, or `std::accumulate`. This facilitates reasoning about termination of loops and sometimes allowed to simplify functions to a single return statement. +- Implemented a `value()` function for JSON pointers (similar to `at` function). +- The Homebrew formula (see [Integration](https://github.com/nlohmann/json#integration)) is now tested for all Xcode builds (6.1 - 8.x) with Travis. +- Avoided output to `std::cout` in the test cases. + +## v2.0.1 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.1/json.hpp) (321 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.1/json.hpp.asc) (1 KB) + +- Release date: 2016-06-28 +- SHA-256: ef550fcd7df572555bf068e9ec4e9d3b9e4cdd441cecb0dcea9ea7fd313f72dd + +### Summary + +This release fixes a performance regression in the JSON serialization (function `dump()`). This fix is backwards compatible. + +### Changes +- The locale of the output stream (or the internal string stream if a JSON value is serialized to a string) is now adjusted once for the whole serialization instead of for each floating-point number. +- The locale of an output stream is now correctly reset to the previous value by the JSON library. + + +## v2.0.0 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.0/json.hpp) (321 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.0/json.hpp.asc) (1 KB) + +- Release date: 2016-06-24 +- SHA-256: ac9e1fb25c2ac9ca5fc501fcd2fe3281fe04f07018a1b48820e7b1b11491bb6c + +### Summary + +This release adds several features such as JSON Pointers, JSON Patch, or support for 64 bit unsigned integers. Furthermore, several (subtle) bugs have been fixed. + +As `noexcept` and `constexpr` specifier have been added to several functions, the public API has effectively been changed in a (potential) non-backwards compatible manner. As we adhere to [Semantic Versioning](http://semver.org), this calls for a new major version, so say hello to 2️⃣.0️⃣.0️⃣. + +### Changes +- 🔟 A JSON value now uses `uint64_t` (default value for template parameter `NumberUnsignedType`) as data type for **unsigned integer** values. This type is used automatically when an unsigned number is parsed. Furthermore, constructors, conversion operators and an `is_number_unsigned()` test have been added. +- 👉 **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) support: A JSON Pointer is a string (similar to an XPath expression) to address a value inside a structured JSON value. JSON Pointers can be used in `at()` and `operator[]` functions. Furthermore, JSON values can be “flattened” to key/value pairs using `flatten()` where each key is a JSON Pointer. The original value can be restored by “unflattening” the flattened value using `unflatten()`. +- 🏥 **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) support. A JSON Patch is a JSON value that describes the required edit operations (add, change, remove, …) to transform a JSON value into another one. A JSON Patch can be created with function `diff(const basic_json&)` and applied with `patch(const basic_json&)`. Note the created patches use a rather primitive algorithm so far and leave room for improvement. +- 🇪🇺 The code is now **locale-independent**: Floating-point numbers are always serialized with a period (`.`) as decimal separator and ignores different settings from the locale. +- 🍺 **Homebrew** support: Install the library with `brew tap nlohmann/json && brew install nlohmann_json`. +- Added constructor to create a JSON value by parsing a `std::istream` (e.g., `std::stringstream` or `std::ifstream`). +- Added **`noexcept`** specifier to `basic_json(boolean_t)`, `basic_json(const number_integer_t)`, `basic_json(const int)`, `basic_json(const number_float_t)`, iterator functions (`begin()`, `end()`, etc.) +- When parsing numbers, the sign of `0.0` (vs. `-0.0`) is preserved. +- Improved MSVC 2015, Android, and MinGW support. See [README](https://github.com/nlohmann/json#supported-compilers) for more information. +- Improved test coverage (added 2,225,386 tests). +- Removed some misuses of `std::move`. +- Fixed several compiler warnings. +- Improved error messages from JSON parser. +- Updated to [`re2c`](http://re2c.org) to version 0.16 to use a minimal DFAs for the lexer. +- Updated test suite to use [Catch](https://github.com/philsquared/Catch) version 1.5.6. +- Made type getters (`is_number`, etc.) and const value access `constexpr`. +- Functions `push_back` and `operator+=` now work with key/value pairs passed as initializer list, e.g. `j_object += {"key", 1}`. +- Overworked `CMakeLists.txt` to make it easier to integrate the library into other projects. + +### Notes +- Parser error messages are still very vague and contain no information on the error location. +- The implemented `diff` function is rather primitive and does not create minimal diffs. +- The name of function `iteration_wrapper` may change in the future and the function will be deprecated in the next release. +- Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that [RFC 8259](https://tools.ietf.org/html/rfc8259) defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like [Native JSON Benchmark](https://github.com/miloyip/nativejson-benchmark) treat roundtripping deviations as conformance errors. + + +## v1.1.0 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v1.1.0/json.hpp) (257 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v1.1.0/json.hpp.asc) (1 KB) + +- Release date: 2016-01-24 +- SHA-256: c0cf0e3017798ca6bb18e757ebc570d21a3bdac877845e2b9e9573d183ed2f05 + +### Summary + +This release fixes several small bugs and adds functionality in a backwards-compatible manner. Compared to the [last version (1.0.0)](https://github.com/nlohmann/json/releases/tag/v1.0.0), the following changes have been made: + +### Changes +- _Fixed_: **Floating-point numbers** are now serialized and deserialized properly such that rountripping works in more cases. [#185, #186, #190, #191, #194] +- _Added_: The code now contains **assertions** to detect undefined behavior during development. As the standard function `assert` is used, the assertions can be switched off by defining the preprocessor symbol `NDEBUG` during compilation. [#168] +- _Added_: It is now possible to get a **reference** to the stored values via the newly added function `get_ref()`. [#128, #184] +- _Fixed_: Access to object values via keys (**`operator[]`**) now works with all kind of string representations. [#171, #189] +- _Fixed_: The code now compiles again with **Microsoft Visual Studio 2015**. [#144, #167, #188] +- _Fixed_: All required headers are now included. +- _Fixed_: Typos and other small issues. [#162, #166, #175, #177, #179, #180] + +### Notes + +There are still known open issues (#178, #187) which will be fixed in version 2.0.0. However, these fixes will require a small API change and will not be entirely backwards-compatible. + + +## v1.0.0 + +!!! summary "Files" + + - [json.hpp](https://github.com/nlohmann/json/releases/download/v1.0.0/json.hpp) (243 KB) + - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v1.0.0/json.hpp.asc) (1 KB) + +- Release date: 2015-12-28 +- SHA-256: 767dc2fab1819d7b9e19b6e456d61e38d21ef7182606ecf01516e3f5230446de + +### Summary + +This is the first official release. Compared to the [prerelease version 1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1), only a few minor improvements have been made: + +### Changes +- _Changed_: A **UTF-8 byte order mark** is silently ignored. +- _Changed_: `sprintf` is no longer used. +- _Changed_: `iterator_wrapper` also works for const objects; note: the name may change! +- _Changed_: **Error messages** during deserialization have been improved. +- _Added_: The `parse` function now also works with type `std::istream&&`. +- _Added_: Function `value(key, default_value)` returns either a copy of an object's element at the specified key or a given default value if no element with the key exists. +- _Added_: Public functions are tagged with the version they were introduced. This shall allow for better **versioning** in the future. +- _Added_: All public functions and types are **documented** (see http://nlohmann.github.io/json/doxygen/) including executable examples. +- _Added_: Allocation of all types (in particular arrays, strings, and objects) is now exception-safe. +- _Added_: They descriptions of thrown exceptions have been overworked and are part of the tests suite and documentation. diff --git a/json-develop/docs/mkdocs/docs/home/sponsors.md b/json-develop/docs/mkdocs/docs/home/sponsors.md new file mode 100644 index 0000000..9097049 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/home/sponsors.md @@ -0,0 +1,13 @@ +# Sponsors + +You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann). + +## Named Sponsors + +- [Michael Hartmann](https://github.com/reFX-Mike) +- [Stefan Hagen](https://github.com/sthagen) +- [Steve Sperandeo](https://github.com/homer6) +- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe) +- [Steve Wagner](https://github.com/ciroque) + +Thanks everyone! diff --git a/json-develop/docs/mkdocs/docs/images/callback_events.png b/json-develop/docs/mkdocs/docs/images/callback_events.png new file mode 100644 index 0000000..09aa2b3 Binary files /dev/null and b/json-develop/docs/mkdocs/docs/images/callback_events.png differ diff --git a/json-develop/docs/mkdocs/docs/images/json_syntax_number.png b/json-develop/docs/mkdocs/docs/images/json_syntax_number.png new file mode 100644 index 0000000..be23ffa Binary files /dev/null and b/json-develop/docs/mkdocs/docs/images/json_syntax_number.png differ diff --git a/json-develop/docs/mkdocs/docs/images/range-begin-end.svg b/json-develop/docs/mkdocs/docs/images/range-begin-end.svg new file mode 100644 index 0000000..8e2b2fb --- /dev/null +++ b/json-develop/docs/mkdocs/docs/images/range-begin-end.svg @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + diff --git a/json-develop/docs/mkdocs/docs/images/range-rbegin-rend.svg b/json-develop/docs/mkdocs/docs/images/range-rbegin-rend.svg new file mode 100644 index 0000000..dc6045f --- /dev/null +++ b/json-develop/docs/mkdocs/docs/images/range-rbegin-rend.svg @@ -0,0 +1,1232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + + + + + + + + + + + + + + + + + + + + + Reversed sequence + + Reverse past-the-last element + + + + + + + + rend + + + + rbegin + + + Reverse iterator stores an iterator to the nextelement than the one it actually refers to + + + + + + + + + diff --git a/json-develop/docs/mkdocs/docs/index.md b/json-develop/docs/mkdocs/docs/index.md new file mode 100644 index 0000000..0e49c83 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/index.md @@ -0,0 +1,3 @@ +# JSON for Modern C++ + +![](images/json.gif) diff --git a/json-develop/docs/mkdocs/docs/integration/cmake.md b/json-develop/docs/mkdocs/docs/integration/cmake.md new file mode 100644 index 0000000..c8f9883 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/cmake.md @@ -0,0 +1,172 @@ +# CMake + +## Integration + +You can use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage +requirements for [`INTERFACE_INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html) +to point to the appropriate include directories and [`INTERFACE_COMPILE_FEATURES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_COMPILE_FEATURES.html) +for the necessary C++11 flags. + +### External + +To use this library from a CMake project, you can locate it directly with [`find_package()`](https://cmake.org/cmake/help/latest/command/find_package.html) +and use the namespaced imported target from the generated package configuration: + +!!! example + + ```cmake title="CMakeLists.txt" + cmake_minimum_required(VERSION 3.1) + project(ExampleProject LANGUAGES CXX) + + find_package(nlohmann_json 3.11.2 REQUIRED) + + add_executable(example example.cpp) + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + +The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of +the build tree. + +### Embedded + +To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call +`add_subdirectory()` in your `CMakeLists.txt` file. + +!!! example + + ```cmake title="CMakeLists.txt" + cmake_minimum_required(VERSION 3.1) + project(ExampleProject LANGUAGES CXX) + + # If you only include this third party in PRIVATE source files, you do not need to install it + # when your main project gets installed. + set(JSON_Install OFF CACHE INTERNAL "") + + add_subdirectory(nlohmann_json) + + add_executable(example example.cpp) + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + +!!! note + + Do not use `#!cmake include(nlohmann_json/CMakeLists.txt)`, since that carries with it unintended consequences that + will break the build. It is generally discouraged (although not necessarily well documented as such) to use + `#!cmake include(...)` for pulling in other CMake projects anyways. + + +### Supporting Both + +To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin +to the following. + +!!! example + + ```cmake title="CMakeLists.txt" + project(ExampleProject LANGUAGES CXX) + + option(EXAMPLE_USE_EXTERNAL_JSON "Use an external JSON library" OFF) + + add_subdirectory(thirdparty) + + add_executable(example example.cpp) + + # Note that the namespaced target will always be available regardless of the import method + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + + ```cmake title="thirdparty/CMakeLists.txt" + if(EXAMPLE_USE_EXTERNAL_JSON) + find_package(nlohmann_json 3.11.2 REQUIRED) + else() + set(JSON_BuildTests OFF CACHE INTERNAL "") + add_subdirectory(nlohmann_json) + endif() + ``` + + `thirdparty/nlohmann_json` is then a complete copy of this source tree. + + +### FetchContent + +Since CMake v3.11, [FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can be used to +automatically download a release as a dependency at configure type. + +!!! example + + ```cmake title="CMakeLists.txt" + cmake_minimum_required(VERSION 3.11) + project(ExampleProject LANGUAGES CXX) + + include(FetchContent) + + FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz) + FetchContent_MakeAvailable(json) + + add_executable(example example.cpp) + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + +!!! Note + + It is recommended to use the URL approach described above which is supported as of version 3.10.0. It is also + possible to pass the Git repository like + + ```cmake + FetchContent_Declare(json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG v3.11.2 + ) + ``` + + However, the repository download size is quite large. You might want to depend on + a smaller repository. For instance, you might want to replace the URL in the example by + . + +## CMake Options + +### `JSON_BuildTests` + +Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option. + +### `JSON_CI` + +Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default. + +### `JSON_Diagnostics` + +Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default. + +### `JSON_DisableEnumSerialization` + +Disable default `enum` serialization by defining the macro +[`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). This option is `OFF` by default. + +### `JSON_FastTests` + +Skip expensive/slow test suites. This option is `OFF` by default. Depends on `JSON_BuildTests`. + +### `JSON_GlobalUDLs` + +Place user-defined string literals in the global namespace by defining the macro +[`JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md). This option is `OFF` by default. + +### `JSON_ImplicitConversions` + +Enable implicit conversions by defining macro [`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md). This option is `ON` by default. + +### `JSON_Install` + +Install CMake targets during install step. This option is `ON` by default if the library's CMake project is the top project. + +### `JSON_MultipleHeaders` + +Use non-amalgamated version of the library. This option is `OFF` by default. + +### `JSON_SystemInclude` + +Treat the library headers like system headers (i.e., adding `SYSTEM` to the [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) call) to checks for this library by tools like Clang-Tidy. This option is `OFF` by default. + +### `JSON_Valgrind` + +Execute test suite with [Valgrind](https://valgrind.org). This option is `OFF` by default. Depends on `JSON_BuildTests`. diff --git a/json-develop/docs/mkdocs/docs/integration/conan/CMakeLists.txt b/json-develop/docs/mkdocs/docs/integration/conan/CMakeLists.txt new file mode 100644 index 0000000..fd3e9ca --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/conan/CMakeLists.txt @@ -0,0 +1,9 @@ +project(json_example) +cmake_minimum_required(VERSION 2.8.12) +add_definitions("-std=c++11") + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(json_example example.cpp) +target_link_libraries(json_example ${CONAN_LIBS}) diff --git a/json-develop/docs/mkdocs/docs/integration/conan/Conanfile.txt b/json-develop/docs/mkdocs/docs/integration/conan/Conanfile.txt new file mode 100644 index 0000000..a8a3e70 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/conan/Conanfile.txt @@ -0,0 +1,5 @@ +[requires] +nlohmann_json/3.7.3 + +[generators] +cmake diff --git a/json-develop/docs/mkdocs/docs/integration/conan/example.cpp b/json-develop/docs/mkdocs/docs/integration/conan/example.cpp new file mode 100644 index 0000000..e5a31be --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/conan/example.cpp @@ -0,0 +1,9 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << json::meta() << std::endl; +} diff --git a/json-develop/docs/mkdocs/docs/integration/example.cpp b/json-develop/docs/mkdocs/docs/integration/example.cpp new file mode 100644 index 0000000..1a7ac4d --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/example.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::setw(4) << json::meta() << std::endl; +} diff --git a/json-develop/docs/mkdocs/docs/integration/index.md b/json-develop/docs/mkdocs/docs/integration/index.md new file mode 100644 index 0000000..2bbaa86 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/index.md @@ -0,0 +1,18 @@ +# Header only + +[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required +file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add + +```cpp +#include + +// for convenience +using json = nlohmann::json; +``` + +to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and +Clang). + +You can further use file +[`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) +for forward declarations. diff --git a/json-develop/docs/mkdocs/docs/integration/migration_guide.md b/json-develop/docs/mkdocs/docs/integration/migration_guide.md new file mode 100644 index 0000000..69dc7ec --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/migration_guide.md @@ -0,0 +1,264 @@ +# Migration Guide + +This page collects some guidelines on how to future-proof your code for future versions of this library. + +## Replace deprecated functions + +The following functions have been deprecated and will be removed in the next major version (i.e., 4.0.0). All +deprecations are annotated with +[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which +function to use instead. + +#### Parsing + +- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use + [`friend std::istream& operator>>(std::istream&, basic_json&)`](../api/operator_gtgt.md) instead. + + === "Deprecated" + + ```cpp + nlohmann::json j; + std::stringstream ss("[1,2,3]"); + j << ss; + ``` + + === "Future-proof" + + ```cpp + nlohmann::json j; + std::stringstream ss("[1,2,3]"); + ss >> j; + ``` + +- Passing iterator pairs or pointer/length pairs to parsing functions ([`parse`](../api/basic_json/parse.md), + [`accept`](../api/basic_json/accept.md), [`sax_parse`](../api/basic_json/sax_parse.md), + [`from_cbor`](../api/basic_json/from_cbor.md), [`from_msgpack`](../api/basic_json/from_msgpack.md), + [`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md) via initializer + lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of + `from_cbor({ptr, len})`. + + === "Deprecated" + + ```cpp + const char* s = "[1,2,3]"; + bool ok = nlohmann::json::accept({s, s + std::strlen(s)}); + ``` + + === "Future-proof" + + ```cpp + const char* s = "[1,2,3]"; + bool ok = nlohmann::json::accept(s, s + std::strlen(s)); + ``` + +#### JSON Pointers + +- Comparing JSON Pointers with strings via [`operator==`](../api/json_pointer/operator_eq.md) and + [`operator!=`](../api/json_pointer/operator_ne.md) is deprecated since 3.11.2. To compare a + [`json_pointer`](../api/json_pointer/index.md) `p` with a string `s`, convert `s` to a `json_pointer` first and use + [`json_pointer::operator==`](../api/json_pointer/operator_eq.md) or + [`json_pointer::operator!=`](../api/json_pointer/operator_ne.md). + + === "Deprecated" + + ```cpp + nlohmann::json::json_pointer lhs("/foo/bar/1"); + assert(lhs == "/foo/bar/1"); + ``` + + === "Future-proof" + + ```cpp + nlohmann::json::json_pointer lhs("/foo/bar/1"); + assert(lhs == nlohmann::json::json_pointer("/foo/bar/1")); + ``` + +- The implicit conversion from JSON Pointers to string + ([`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md)) is deprecated since 3.11.0. Use + [`json_pointer::to_string`](../api/json_pointer/to_string.md) instead. + + === "Deprecated" + + ```cpp + nlohmann::json::json_pointer ptr("/foo/bar/1"); + std::string s = ptr; + ``` + + === "Future-proof" + + ```cpp + nlohmann::json::json_pointer ptr("/foo/bar/1"); + std::string s = ptr.to_string(); + ``` + +- Passing a `basic_json` specialization as template parameter `RefStringType` to + [`json_pointer`](../api/json_pointer/index.md) is deprecated since 3.11.0. The string type can now be directly + provided. + + === "Deprecated" + + ```cpp + using my_json = nlohmann::basic_json; + nlohmann::json_pointer ptr("/foo/bar/1"); + ``` + + === "Future-proof" + + ```cpp + nlohmann::json_pointer ptr("/foo/bar/1"); + ``` + + Thereby, `nlohmann::my_json::json_pointer` is an alias for `nlohmann::json_pointer` and is always an + alias to the `json_pointer` with the appropriate string type for all specializations of `basic_json`. + +#### Miscellaneous functions + +- The function `iterator_wrapper` is deprecated since 3.1.0. Please use the member function + [`items`](../api/basic_json/items.md) instead. + + === "Deprecated" + + ```cpp + for (auto &x : nlohmann::json::iterator_wrapper(j)) + { + std::cout << x.key() << ":" << x.value() << std::endl; + } + ``` + + === "Future-proof" + + ```cpp + for (auto &x : j.items()) + { + std::cout << x.key() << ":" << x.value() << std::endl; + } + ``` + +- Function `friend std::ostream& operator>>(const basic_json&, std::ostream&)` is deprecated since 3.0.0. Please use + [`friend operator<<(std::ostream&, const basic_json&)`](../api/operator_ltlt.md) instead. + + === "Deprecated" + + ```cpp + j >> std::cout; + ``` + + === "Future-proof" + + ```cpp + std::cout << j; + ``` + +- The legacy comparison behavior for discarded values is deprecated since 3.11.0. It is already disabled by default and + can still be enabled by defining + [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md) to `1`. + + === "Deprecated" + + ```cpp + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 + #include + ``` + + === "Future-proof" + + ```cpp + #include + ``` + +## Replace implicit conversions + +Implicit conversions via [`operator ValueType`](../api/basic_json/operator_ValueType.md) will be switched off by default +in the next major release of the library. + +You can prepare existing code by already defining +[`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) to `0` and replace any implicit +conversions with calls to [`get`](../api/basic_json/get.md), [`get_to`](../api/basic_json/get_to.md), +[`get_ref`](../api/basic_json/get_ref.md), or [`get_ptr`](../api/basic_json/get_ptr.md). + +=== "Deprecated" + + ```cpp + nlohmann::json j = "Hello, world!"; + std::string s = j; + ``` + +=== "Future-proof" + + ```cpp + nlohmann::json j = "Hello, world!"; + auto s = j.get(); + ``` + +=== "Future-proof (alternative)" + + ```cpp + nlohmann::json j = "Hello, world!"; + std::string s; + j.get_to(s); + ``` + +You can prepare existing code by already defining +[`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) to `0` and replace any implicit +conversions with calls to [`get`](../api/basic_json/get.md). + +## Import namespace `literals` for UDLs + +The user-defined string literals [`operator""_json`](../api/operator_literal_json.md) and +[`operator""_json_pointer`](../api/operator_literal_json_pointer.md) will be removed from the global namespace in the +next major release of the library. + +=== "Deprecated" + + ```cpp + nlohmann::json j = "[1,2,3]"_json; + ``` + +=== "Future-proof" + + ```cpp + using namespace nlohmann::literals; + nlohmann::json j = "[1,2,3]"_json; + ``` + +To prepare existing code, define [`JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md) to `0` and bring the +string literals into scope where needed. + +## Do not hard-code the complete library namespace + +The [`nlohmann` namespace](../features/namespace.md) contains a sub-namespace to avoid problems when different +versions or configurations of the library are used in the same project. Always use `nlohmann` as namespace or, when the +exact version and configuration is relevant, use macro +[`NLOHMANN_JSON_NAMESPACE`](../api/macros/nlohmann_json_namespace.md) to denote the namespace. + +=== "Dangerous" + + ```cpp + void to_json(nlohmann::json_abi_v3_11_2::json& j, const person& p) + { + j["age"] = p.age; + } + ``` + +=== "Future-proof" + + ```cpp + void to_json(nlohmann::json& j, const person& p) + { + j["age"] = p.age; + } + ``` + +=== "Future-proof (alternative)" + + ```cpp + void to_json(NLOHMANN_JSON_NAMESPACE::json& j, const person& p) + { + j["age"] = p.age; + } + ``` + +## Do not use the `details` namespace + +The `details` namespace is not part of the public API of the library and can change in any version without announcement. +Do not rely on any function or type in the `details` namespace. diff --git a/json-develop/docs/mkdocs/docs/integration/package_managers.md b/json-develop/docs/mkdocs/docs/integration/package_managers.md new file mode 100644 index 0000000..46d7a85 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/package_managers.md @@ -0,0 +1,198 @@ +# Package Managers + +Throughout this page, we will describe how to compile the example file `example.cpp` below. + +```cpp +--8<-- "integration/example.cpp" +``` + +When executed, this program should create output similar to + +```json +--8<-- "../../examples/meta.output" +``` + +## Homebrew + +If you are using OS X and [Homebrew](http://brew.sh), just type + +```sh +brew install nlohmann-json +``` + +and you're set. If you want the bleeding edge rather than the latest release, use + +```sh +brew install nlohmann-json --HEAD +``` + +instead. See [nlohmann-json](https://formulae.brew.sh/formula/nlohmann-json) for more information. + +??? example + + 1. Create the following file: + + ```cpp title="example.cpp" + --8<-- "integration/example.cpp" + ``` + + 2. Install the package + + ```sh + brew install nlohmann-json + ``` + + 3. Determine the include path, which defaults to `/usr/local/Cellar/nlohmann-json/$version/include`, where `$version` is the version of the library, e.g. `3.7.3`. The path of the library can be determined with + + ```sh + brew list nlohmann-json + ``` + + 4. Compile the code. For instance, the code can be compiled using Clang with + + ```sh + clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std=c++11 -o example + ``` + +:material-update: The [formula](https://formulae.brew.sh/formula/nlohmann-json) is updated automatically. + +## Meson + +If you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging. + +The provided `meson.build` can also be used as an alternative to cmake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly. + +## Bazel + +This repository provides a [Bazel](https://bazel.build/) `WORKSPACE.bazel` and a corresponding `BUILD.bazel` file. Therefore, this repository can be referenced by workspace rules such as `http_archive`, `git_repository`, or `local_repository` from other Bazel workspaces. To use the library you only need to depend on the target `@nlohmann_json//:json` (e.g. via `deps` attribute). + +## Conan + +If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages. + +??? example + + 1. Create the following files: + + ```ini title="Conanfile.txt" + --8<-- "integration/conan/Conanfile.txt" + ``` + + ```cmake title="CMakeLists.txt" + --8<-- "integration/conan/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/conan/example.cpp" + ``` + + 2. Build: + + ```sh + mkdir build + cd build + conan install .. + cmake .. + cmake --build . + ``` + +:material-update: The [package](https://conan.io/center/nlohmann_json) is updated automatically. + +## Spack + +If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging. + +## Hunter + +If you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging. + +## Buckaroo + +If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example). + +## vcpkg + +If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can install the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) with `vcpkg install nlohmann-json` and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging. + +??? example + + 1. Create the following files: + + ```cmake title="CMakeLists.txt" + --8<-- "integration/vcpkg/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/vcpkg/example.cpp" + ``` + + 2. Install package: + + ```sh + vcpkg install nlohmann-json + ``` + + 3. Build: + + ```sh + mkdir build + cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake + cmake --build . + ``` + + Note you need to adjust `/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake` to your system. + +## cget + +If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`). + +:material-update: cget reads directly from the [GitHub repository](https://github.com/nlohmann/json) and is always up-to-date. + +## CocoaPods + +If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open). + +## NuGet + +If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please file issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues). + +## Conda + +If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues). + +## MSYS2 + +If you are using [MSYS2](http://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages. + +:material-update: The [package](https://packages.msys2.org/base/mingw-w64-nlohmann-json) is updated automatically. + +## MacPorts + +If you are using [MacPorts](https://ports.macports.org), execute `sudo port install nlohmann-json` to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package. + +:material-update: The [package](https://ports.macports.org/port/nlohmann-json/) is updated automatically. + +## build2 + +If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml). +Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages. + +:material-update: The [package](https://cppget.org/nlohmann-json) is updated automatically. + +## wsjcpp + +If you are using [`wsjcpp`](http://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch. + +:material-update: wsjcpp reads directly from the [GitHub repository](https://github.com/nlohmann/json) and is always up-to-date. + +## CPM.cmake + +If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake: + +```cmake +CPMAddPackage( + NAME nlohmann_json + GITHUB_REPOSITORY nlohmann/json + VERSION 3.9.1) +``` diff --git a/json-develop/docs/mkdocs/docs/integration/pkg-config.md b/json-develop/docs/mkdocs/docs/integration/pkg-config.md new file mode 100644 index 0000000..429d0de --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/pkg-config.md @@ -0,0 +1,13 @@ +# Pkg-config + +If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed: + +```sh +pkg-config nlohmann_json --cflags +``` + +Users of the [Meson build system](package_managers.md#meson) will also be able to use a system-wide library, which will be found by `pkg-config`: + +```meson +json = dependency('nlohmann_json', required: true) +``` diff --git a/json-develop/docs/mkdocs/docs/integration/vcpkg/CMakeLists.txt b/json-develop/docs/mkdocs/docs/integration/vcpkg/CMakeLists.txt new file mode 100644 index 0000000..d31f4e8 --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/vcpkg/CMakeLists.txt @@ -0,0 +1,7 @@ +project(json_example) +cmake_minimum_required(VERSION 2.8.12) + +find_package(nlohmann_json CONFIG REQUIRED) + +add_executable(json_example example.cpp) +target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) diff --git a/json-develop/docs/mkdocs/docs/integration/vcpkg/example.cpp b/json-develop/docs/mkdocs/docs/integration/vcpkg/example.cpp new file mode 100644 index 0000000..e5a31be --- /dev/null +++ b/json-develop/docs/mkdocs/docs/integration/vcpkg/example.cpp @@ -0,0 +1,9 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << json::meta() << std::endl; +} diff --git a/json-develop/docs/mkdocs/mkdocs.yml b/json-develop/docs/mkdocs/mkdocs.yml new file mode 100644 index 0000000..8319354 --- /dev/null +++ b/json-develop/docs/mkdocs/mkdocs.yml @@ -0,0 +1,365 @@ +# Project information +site_name: JSON for Modern C++ +site_author: Niels Lohmann +site_url: https://json.nlohmann.me/ + +# Repository +repo_name: nlohmann/json +repo_url: https://github.com/nlohmann/json +edit_uri: edit/develop/docs/mkdocs/docs + +# Copyright +copyright: Copyright © 2013 - 2022 Niels Lohmann + +# Configuration +theme: + name: material + language: en + palette: + - media: '(prefers-color-scheme: light)' + scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + primary: indigo + accent: indigo + toggle: + icon: material/brightness-4 + name: Switch to light mode + + font: + text: Roboto + code: JetBrains Mono + features: + - navigation.instant + - navigation.tracking + - navigation.tabs + - navigation.indexes + - navigation.top + - content.tabs.link + +nav: + - Home: + - index.md + - home/license.md + - "Code of Conduct": home/code_of_conduct.md + - "FAQ": home/faq.md + - home/exceptions.md + - home/releases.md + - home/design_goals.md + - home/sponsors.md + - Features: + - features/arbitrary_types.md + - Binary Formats: + - features/binary_formats/index.md + - features/binary_formats/bjdata.md + - features/binary_formats/bson.md + - features/binary_formats/cbor.md + - features/binary_formats/messagepack.md + - features/binary_formats/ubjson.md + - features/binary_values.md + - features/comments.md + - Element Access: + - features/element_access/index.md + - features/element_access/unchecked_access.md + - features/element_access/checked_access.md + - features/element_access/default_value.md + - features/iterators.md + - features/json_pointer.md + - features/json_patch.md + - features/merge_patch.md + - 'nlohmann Namespace': features/namespace.md + - features/object_order.md + - Parsing: + - features/parsing/index.md + - features/parsing/json_lines.md + - features/parsing/parse_exceptions.md + - features/parsing/parser_callbacks.md + - features/parsing/sax_interface.md + - features/assertions.md + - features/enum_conversion.md + - features/macros.md + - Types: + - features/types/index.md + - features/types/number_handling.md + - Integration: + - integration/index.md + - integration/migration_guide.md + - integration/cmake.md + - integration/package_managers.md + - integration/pkg-config.md + - API Documentation: + - basic_json: + - 'Overview': api/basic_json/index.md + - '(Constructor)': api/basic_json/basic_json.md + - '(Destructor)': api/basic_json/~basic_json.md + - 'accept': api/basic_json/accept.md + - 'array': api/basic_json/array.md + - 'array_t': api/basic_json/array_t.md + - 'at': api/basic_json/at.md + - 'back': api/basic_json/back.md + - 'begin': api/basic_json/begin.md + - 'binary': api/basic_json/binary.md + - 'binary_t': api/basic_json/binary_t.md + - 'boolean_t': api/basic_json/boolean_t.md + - 'cbegin': api/basic_json/cbegin.md + - 'cbor_tag_handler_t': api/basic_json/cbor_tag_handler_t.md + - 'cend': api/basic_json/cend.md + - 'clear': api/basic_json/clear.md + - 'contains': api/basic_json/contains.md + - 'count': api/basic_json/count.md + - 'crbegin': api/basic_json/crbegin.md + - 'crend': api/basic_json/crend.md + - 'default_object_comparator_t': api/basic_json/default_object_comparator_t.md + - 'diff': api/basic_json/diff.md + - 'dump': api/basic_json/dump.md + - 'emplace': api/basic_json/emplace.md + - 'emplace_back': api/basic_json/emplace_back.md + - 'empty': api/basic_json/empty.md + - 'end': api/basic_json/end.md + - 'erase': api/basic_json/erase.md + - 'error_handler_t': api/basic_json/error_handler_t.md + - 'exception': api/basic_json/exception.md + - 'find': api/basic_json/find.md + - 'flatten': api/basic_json/flatten.md + - 'from_bjdata': api/basic_json/from_bjdata.md + - 'from_bson': api/basic_json/from_bson.md + - 'from_cbor': api/basic_json/from_cbor.md + - 'from_msgpack': api/basic_json/from_msgpack.md + - 'from_ubjson': api/basic_json/from_ubjson.md + - 'front': api/basic_json/front.md + - 'get': api/basic_json/get.md + - 'get_allocator': api/basic_json/get_allocator.md + - 'get_binary': api/basic_json/get_binary.md + - 'get_ptr': api/basic_json/get_ptr.md + - 'get_ref': api/basic_json/get_ref.md + - 'get_to': api/basic_json/get_to.md + - 'std::hash<basic_json>': api/basic_json/std_hash.md + - 'input_format_t': api/basic_json/input_format_t.md + - 'insert': api/basic_json/insert.md + - 'invalid_iterator': api/basic_json/invalid_iterator.md + - 'is_array': api/basic_json/is_array.md + - 'is_binary': api/basic_json/is_binary.md + - 'is_boolean': api/basic_json/is_boolean.md + - 'is_discarded': api/basic_json/is_discarded.md + - 'is_null': api/basic_json/is_null.md + - 'is_number': api/basic_json/is_number.md + - 'is_number_float': api/basic_json/is_number_float.md + - 'is_number_integer': api/basic_json/is_number_integer.md + - 'is_number_unsigned': api/basic_json/is_number_unsigned.md + - 'is_object': api/basic_json/is_object.md + - 'is_primitive': api/basic_json/is_primitive.md + - 'is_string': api/basic_json/is_string.md + - 'is_structured': api/basic_json/is_structured.md + - 'items': api/basic_json/items.md + - 'json_base_class_t': api/basic_json/json_base_class_t.md + - 'json_serializer': api/basic_json/json_serializer.md + - 'max_size': api/basic_json/max_size.md + - 'meta': api/basic_json/meta.md + - 'merge_patch': api/basic_json/merge_patch.md + - 'number_float_t': api/basic_json/number_float_t.md + - 'number_integer_t': api/basic_json/number_integer_t.md + - 'number_unsigned_t': api/basic_json/number_unsigned_t.md + - 'object': api/basic_json/object.md + - 'object_comparator_t': api/basic_json/object_comparator_t.md + - 'object_t': api/basic_json/object_t.md + - 'operator ValueType': api/basic_json/operator_ValueType.md + - 'operator value_t': api/basic_json/operator_value_t.md + - 'operator[]': api/basic_json/operator[].md + - 'operator=': api/basic_json/operator=.md + - 'operator+=': api/basic_json/operator+=.md + - 'operator==': api/basic_json/operator_eq.md + - 'operator!=': api/basic_json/operator_ne.md + - 'operator<': api/basic_json/operator_lt.md + - 'operator>': api/basic_json/operator_gt.md + - 'operator<=': api/basic_json/operator_le.md + - 'operator>=': api/basic_json/operator_ge.md + - 'operator<=>': api/basic_json/operator_spaceship.md + - 'out_of_range': api/basic_json/out_of_range.md + - 'other_error': api/basic_json/other_error.md + - 'parse': api/basic_json/parse.md + - 'parse_error': api/basic_json/parse_error.md + - 'parse_event_t': api/basic_json/parse_event_t.md + - 'parser_callback_t': api/basic_json/parser_callback_t.md + - 'patch': api/basic_json/patch.md + - 'patch_inplace': api/basic_json/patch_inplace.md + - 'push_back': api/basic_json/push_back.md + - 'rbegin': api/basic_json/rbegin.md + - 'rend': api/basic_json/rend.md + - 'sax_parse': api/basic_json/sax_parse.md + - 'size': api/basic_json/size.md + - 'string_t': api/basic_json/string_t.md + - 'swap': api/basic_json/swap.md + - 'std::swap<basic_json>': api/basic_json/std_swap.md + - 'to_bjdata': api/basic_json/to_bjdata.md + - 'to_bson': api/basic_json/to_bson.md + - 'to_cbor': api/basic_json/to_cbor.md + - 'to_msgpack': api/basic_json/to_msgpack.md + - 'to_string': api/basic_json/to_string.md + - 'to_ubjson': api/basic_json/to_ubjson.md + - 'type': api/basic_json/type.md + - 'type_error': api/basic_json/type_error.md + - 'type_name': api/basic_json/type_name.md + - 'unflatten': api/basic_json/unflatten.md + - 'update': api/basic_json/update.md + - 'value': api/basic_json/value.md + - 'value_t': api/basic_json/value_t.md + - byte_container_with_subtype: + - 'Overview': api/byte_container_with_subtype/index.md + - '(constructor)': api/byte_container_with_subtype/byte_container_with_subtype.md + - 'clear_subtype': api/byte_container_with_subtype/clear_subtype.md + - 'has_subtype': api/byte_container_with_subtype/has_subtype.md + - 'set_subtype': api/byte_container_with_subtype/set_subtype.md + - 'subtype': api/byte_container_with_subtype/subtype.md + - adl_serializer: + - 'Overview': api/adl_serializer/index.md + - 'from_json': api/adl_serializer/from_json.md + - 'to_json': api/adl_serializer/to_json.md + - 'json': api/json.md + - json_pointer: + - 'Overview': api/json_pointer/index.md + - '(Constructor)': api/json_pointer/json_pointer.md + - 'back': api/json_pointer/back.md + - 'empty': api/json_pointer/empty.md + - 'operator string_t': api/json_pointer/operator_string_t.md + - 'operator==': api/json_pointer/operator_eq.md + - 'operator!=': api/json_pointer/operator_ne.md + - 'operator/': api/json_pointer/operator_slash.md + - 'operator/=': api/json_pointer/operator_slasheq.md + - 'parent_pointer': api/json_pointer/parent_pointer.md + - 'pop_back': api/json_pointer/pop_back.md + - 'push_back': api/json_pointer/push_back.md + - 'string_t': api/json_pointer/string_t.md + - 'to_string': api/json_pointer/to_string.md + - json_sax: + - 'Overview': api/json_sax/index.md + - 'binary': api/json_sax/binary.md + - 'boolean': api/json_sax/boolean.md + - 'end_array': api/json_sax/end_array.md + - 'end_object': api/json_sax/end_object.md + - 'key': api/json_sax/key.md + - 'null': api/json_sax/null.md + - 'number_float': api/json_sax/number_float.md + - 'number_integer': api/json_sax/number_integer.md + - 'number_unsigned': api/json_sax/number_unsigned.md + - 'parse_error': api/json_sax/parse_error.md + - 'start_array': api/json_sax/start_array.md + - 'start_object': api/json_sax/start_object.md + - 'string': api/json_sax/string.md + - 'operator<<(basic_json)': api/operator_ltlt.md + - 'operator<<(json_pointer)': api/operator_ltlt.md + - 'operator>>(basic_json)': api/operator_gtgt.md + - 'operator""_json': api/operator_literal_json.md + - 'operator""_json_pointer': api/operator_literal_json_pointer.md + - 'ordered_json': api/ordered_json.md + - 'ordered_map': api/ordered_map.md + - macros: + - 'Overview': api/macros/index.md + - 'JSON_ASSERT': api/macros/json_assert.md + - 'JSON_CATCH_USER': api/macros/json_throw_user.md + - 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md + - 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md + - 'JSON_HAS_CPP_11': api/macros/json_has_cpp_11.md + - 'JSON_HAS_CPP_14': api/macros/json_has_cpp_11.md + - 'JSON_HAS_CPP_17': api/macros/json_has_cpp_11.md + - 'JSON_HAS_CPP_20': api/macros/json_has_cpp_11.md + - 'JSON_HAS_EXPERIMENTAL_FILESYSTEM': api/macros/json_has_filesystem.md + - 'JSON_HAS_FILESYSTEM': api/macros/json_has_filesystem.md + - 'JSON_HAS_RANGES': api/macros/json_has_ranges.md + - 'JSON_HAS_THREE_WAY_COMPARISON': api/macros/json_has_three_way_comparison.md + - 'JSON_NOEXCEPTION': api/macros/json_noexception.md + - 'JSON_NO_IO': api/macros/json_no_io.md + - 'JSON_SKIP_LIBRARY_VERSION_CHECK': api/macros/json_skip_library_version_check.md + - 'JSON_SKIP_UNSUPPORTED_COMPILER_CHECK': api/macros/json_skip_unsupported_compiler_check.md + - 'JSON_THROW_USER': api/macros/json_throw_user.md + - 'JSON_TRY_USER': api/macros/json_throw_user.md + - 'JSON_USE_GLOBAL_UDLS': api/macros/json_use_global_udls.md + - 'JSON_USE_IMPLICIT_CONVERSIONS': api/macros/json_use_implicit_conversions.md + - 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON': api/macros/json_use_legacy_discarded_value_comparison.md + - 'NLOHMANN_DEFINE_TYPE_INTRUSIVE': api/macros/nlohmann_define_type_intrusive.md + - 'NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT': api/macros/nlohmann_define_type_intrusive.md + - 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE': api/macros/nlohmann_define_type_non_intrusive.md + - 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT': api/macros/nlohmann_define_type_non_intrusive.md + - 'NLOHMANN_JSON_NAMESPACE': api/macros/nlohmann_json_namespace.md + - 'NLOHMANN_JSON_NAMESPACE_BEGIN': api/macros/nlohmann_json_namespace_begin.md + - 'NLOHMANN_JSON_NAMESPACE_END': api/macros/nlohmann_json_namespace_begin.md + - 'NLOHMANN_JSON_NAMESPACE_NO_VERSION': api/macros/nlohmann_json_namespace_no_version.md + - 'NLOHMANN_JSON_SERIALIZE_ENUM': api/macros/nlohmann_json_serialize_enum.md + - 'NLOHMANN_JSON_VERSION_MAJOR': api/macros/nlohmann_json_version_major.md + - 'NLOHMANN_JSON_VERSION_MINOR': api/macros/nlohmann_json_version_major.md + - 'NLOHMANN_JSON_VERSION_PATCH': api/macros/nlohmann_json_version_major.md + +# Extras +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/nlohmann + - icon: fontawesome/brands/twitter + link: https://twitter.com/nlohmann + - icon: fontawesome/brands/linkedin + link: https://www.linkedin.com/in/nielslohmann/ + - icon: fontawesome/brands/xing + link: https://www.xing.com/profile/Niels_Lohmann + - icon: fontawesome/brands/paypal + link: https://www.paypal.me/nlohmann + generator: false + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - codehilite: + guess_lang: false + - toc: + permalink: true + - pymdownx.arithmatex + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.critic + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.inlinehilite + - pymdownx.magiclink + - pymdownx.mark + #- pymdownx.smartsymbols + - pymdownx.superfences + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tilde + - pymdownx.snippets: + base_path: docs + check_paths: true + - plantuml_markdown: + format: svg + +plugins: + - search: + separator: '[\s\-\.]' + lang: en + - minify: + minify_html: true + - git-revision-date-localized + - redirects: + redirect_maps: + 'api/basic_json/operator_gtgt.md': api/operator_gtgt.md + 'api/basic_json/operator_ltlt.md': api/operator_ltlt.md + 'api/basic_json/operator_literal_json.md': api/operator_literal_json.md + 'api/basic_json/operator_literal_json_pointer.md': api/operator_literal_json_pointer.md + 'api/json_pointer/operator_string.md': api/json_pointer/operator_string_t.md + +extra_css: + - css/custom.css + +extra_javascript: + - https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML diff --git a/json-develop/docs/mkdocs/requirements.txt b/json-develop/docs/mkdocs/requirements.txt new file mode 100644 index 0000000..26e9fc6 --- /dev/null +++ b/json-develop/docs/mkdocs/requirements.txt @@ -0,0 +1,49 @@ +Babel==2.11.0 +certifi==2022.12.7 +charset-normalizer==2.1.1 +click==8.1.3 +csscompressor==0.9.5 +future==0.18.3 +ghp-import==2.1.0 +gitdb==4.0.10 +GitPython==3.1.29 +htmlmin==0.1.12 +httplib2==0.21.0 +idna==3.4 +importlib-metadata==5.1.0 +Jinja2==3.1.2 +joblib==1.2.0 +jsmin==3.0.1 +livereload==2.6.3 +lunr==0.6.2 +Markdown==3.3.7 # we cannot install a more recent version yet as mkdocs 1.4.2 depends on markdown<3.4 +markdown-include==0.8.0 +MarkupSafe==2.1.1 +mergedeep==1.3.4 +mkdocs==1.4.2 +mkdocs-git-revision-date-localized-plugin==1.1.0 +mkdocs-material==8.5.11 +mkdocs-material-extensions==1.1.1 +mkdocs-minify-plugin==0.6.2 +mkdocs-redirects==1.2.0 +mkdocs-simple-hooks==0.1.5 +nltk==3.8 +packaging==22.0 +plantuml==0.3.0 +plantuml-markdown==3.7.3 +Pygments==2.13.0 +pymdown-extensions==9.9 +pyparsing==3.0.9 +python-dateutil==2.8.2 +pytz==2022.7 +PyYAML==6.0 +pyyaml_env_tag==0.1 +regex==2022.10.31 +requests==2.28.1 +six==1.16.0 +smmap==5.0.0 +tornado==6.2 +tqdm==4.64.1 +urllib3==1.26.13 +watchdog==2.2.0 +zipp==3.11.0 diff --git a/json-develop/docs/mkdocs/scripts/check_structure.py b/json-develop/docs/mkdocs/scripts/check_structure.py new file mode 100644 index 0000000..643482a --- /dev/null +++ b/json-develop/docs/mkdocs/scripts/check_structure.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python + +import glob +import os.path +import re +import sys + +warnings = 0 + + +def report(rule, location, description): + global warnings + warnings += 1 + print(f'{warnings:3}. {location}: {description} [{rule}]') + + +def check_structure(): + expected_sections = [ + 'Template parameters', + 'Specializations', + 'Iterator invalidation', + 'Requirements', + 'Member types', + 'Member functions', + 'Member variables', + 'Static functions', + 'Non-member functions', + 'Literals', + 'Helper classes', + 'Parameters', + 'Return value', + 'Exception safety', + 'Exceptions', + 'Complexity', + 'Possible implementation', + 'Default definition', + 'Notes', + 'Examples', + 'See also', + 'Version history' + ] + + required_sections = [ + 'Examples', + 'Version history' + ] + + files = sorted(glob.glob('api/**/*.md', recursive=True)) + for file in files: + with open(file) as file_content: + section_idx = -1 # the index of the current h2 section + existing_sections = [] # the list of h2 sections in the file + in_initial_code_example = False # whether we are inside the first code example block + previous_line = None # the previous read line + h1sections = 0 # the number of h1 sections in the file + last_overload = 0 # the last seen overload number in the code example + documented_overloads = {} # the overloads that have been documented in the current block + current_section = None # the name of the current section + + for lineno, original_line in enumerate(file_content.readlines()): + line = original_line.strip() + + if line.startswith('# '): + h1sections += 1 + + # there should only be one top-level title + if h1sections > 1: + report('structure/unexpected_section', f'{file}:{lineno+1}', f'unexpected top-level title "{line}"') + h1sections = 1 + + # Overview pages should have a better title + if line == '# Overview': + report('style/title', f'{file}:{lineno+1}', 'overview pages should have a better title than "Overview"') + + # lines longer than 160 characters are bad (unless they are tables) + if len(line) > 160 and '|' not in line: + report('whitespace/line_length', f'{file}:{lineno+1} ({current_section})', f'line is too long ({len(line)} vs. 160 chars)') + + # sections in `` comments are treated as present + if line.startswith('') + existing_sections.append(current_section) + + # check if sections are correct + if line.startswith('## '): + # before starting a new section, check if the previous one documented all overloads + if current_section in documented_overloads and last_overload != 0: + if len(documented_overloads[current_section]) > 0 and len(documented_overloads[current_section]) != last_overload: + expected = list(range(1, last_overload+1)) + undocumented = [x for x in expected if x not in documented_overloads[current_section]] + unexpected = [x for x in documented_overloads[current_section] if x not in expected] + if len(undocumented): + report('style/numbering', f'{file}:{lineno} ({current_section})', f'undocumented overloads: {", ".join([f"({x})" for x in undocumented])}') + if len(unexpected): + report('style/numbering', f'{file}:{lineno} ({current_section})', f'unexpected overloads: {", ".join([f"({x})" for x in unexpected])}') + + current_section = line.strip('## ') + existing_sections.append(current_section) + + if current_section in expected_sections: + idx = expected_sections.index(current_section) + if idx <= section_idx: + report('structure/section_order', f'{file}:{lineno+1}', f'section "{current_section}" is in an unexpected order (should be before "{expected_sections[section_idx]}")') + section_idx = idx + else: + if 'index.md' not in file: # index.md files may have a different structure + report('structure/unknown_section', f'{file}:{lineno+1}', f'section "{current_section}" is not part of the expected sections') + + # collect the numbered items of the current section to later check if they match the number of overloads + if last_overload != 0 and not in_initial_code_example: + if len(original_line) and original_line[0].isdigit(): + number = int(re.findall(r"^(\d+).", original_line)[0]) + if current_section not in documented_overloads: + documented_overloads[current_section] = [] + documented_overloads[current_section].append(number) + + # code example + if line == '```cpp' and section_idx == -1: + in_initial_code_example = True + + if in_initial_code_example and line.startswith('//') and line not in ['// since C++20', '// until C++20']: + # check numbering of overloads + if any(map(str.isdigit, line)): + number = int(re.findall(r'\d+', line)[0]) + if number != last_overload + 1: + report('style/numbering', f'{file}:{lineno+1}', f'expected number ({number}) to be ({last_overload +1 })') + last_overload = number + + if any(map(str.isdigit, line)) and '(' not in line: + report('style/numbering', f'{file}:{lineno+1}', f'number should be in parentheses: {line}') + + if line == '```' and in_initial_code_example: + in_initial_code_example = False + + # consecutive blank lines are bad + if line == '' and previous_line == '': + report('whitespace/blank_lines', f'{file}:{lineno}-{lineno+1} ({current_section})', 'consecutive blank lines') + + # check that non-example admonitions have titles + untitled_admonition = re.match(r'^(\?\?\?|!!!) ([^ ]+)$', line) + if untitled_admonition and untitled_admonition.group(2) != 'example': + report('style/admonition_title', f'{file}:{lineno} ({current_section})', f'"{untitled_admonition.group(2)}" admonitions should have a title') + + previous_line = line + + if 'index.md' not in file: # index.md files may have a different structure + for required_section in required_sections: + if required_section not in existing_sections: + report('structure/missing_section', f'{file}:{lineno+1}', f'required section "{required_section}" was not found') + + +def check_examples(): + example_files = sorted(glob.glob('../../examples/*.cpp')) + markdown_files = sorted(glob.glob('**/*.md', recursive=True)) + + # check if every example file is used in at least one markdown file + for example_file in example_files: + example_file = os.path.join('examples', os.path.basename(example_file)) + + found = False + for markdown_file in markdown_files: + content = ' '.join(open(markdown_file).readlines()) + if example_file in content: + found = True + break + + if not found: + report('examples/missing', f'{example_file}', 'example file is not used in any documentation file') + + +if __name__ == '__main__': + print(120 * '-') + check_structure() + check_examples() + print(120 * '-') + + if warnings > 0: + sys.exit(1) diff --git a/json-develop/docs/usages/ios.png b/json-develop/docs/usages/ios.png new file mode 100644 index 0000000..1d2c1b8 Binary files /dev/null and b/json-develop/docs/usages/ios.png differ diff --git a/json-develop/docs/usages/macos.png b/json-develop/docs/usages/macos.png new file mode 100644 index 0000000..107b5f0 Binary files /dev/null and b/json-develop/docs/usages/macos.png differ diff --git a/json-develop/include/nlohmann/adl_serializer.hpp b/json-develop/include/nlohmann/adl_serializer.hpp new file mode 100644 index 0000000..f77f944 --- /dev/null +++ b/json-develop/include/nlohmann/adl_serializer.hpp @@ -0,0 +1,55 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/// @sa https://json.nlohmann.me/api/adl_serializer/ +template +struct adl_serializer +{ + /// @brief convert a JSON value to any value type + /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ + template + static auto from_json(BasicJsonType && j, TargetType& val) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), val))) + -> decltype(::nlohmann::from_json(std::forward(j), val), void()) + { + ::nlohmann::from_json(std::forward(j), val); + } + + /// @brief convert a JSON value to any value type + /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ + template + static auto from_json(BasicJsonType && j) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) + -> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) + { + return ::nlohmann::from_json(std::forward(j), detail::identity_tag {}); + } + + /// @brief convert any value type to a JSON value + /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/ + template + static auto to_json(BasicJsonType& j, TargetType && val) noexcept( + noexcept(::nlohmann::to_json(j, std::forward(val)))) + -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) + { + ::nlohmann::to_json(j, std::forward(val)); + } +}; + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/byte_container_with_subtype.hpp b/json-develop/include/nlohmann/byte_container_with_subtype.hpp new file mode 100644 index 0000000..1031cdc --- /dev/null +++ b/json-develop/include/nlohmann/byte_container_with_subtype.hpp @@ -0,0 +1,103 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // uint8_t, uint64_t +#include // tie +#include // move + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/// @brief an internal type for a backed binary type +/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/ +template +class byte_container_with_subtype : public BinaryType +{ + public: + using container_type = BinaryType; + using subtype_type = std::uint64_t; + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype() noexcept(noexcept(container_type())) + : container_type() + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) + : container_type(b) + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) + : container_type(b) + , m_subtype(subtype_) + , m_has_subtype(true) + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) + , m_subtype(subtype_) + , m_has_subtype(true) + {} + + bool operator==(const byte_container_with_subtype& rhs) const + { + return std::tie(static_cast(*this), m_subtype, m_has_subtype) == + std::tie(static_cast(rhs), rhs.m_subtype, rhs.m_has_subtype); + } + + bool operator!=(const byte_container_with_subtype& rhs) const + { + return !(rhs == *this); + } + + /// @brief sets the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ + void set_subtype(subtype_type subtype_) noexcept + { + m_subtype = subtype_; + m_has_subtype = true; + } + + /// @brief return the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ + constexpr subtype_type subtype() const noexcept + { + return m_has_subtype ? m_subtype : static_cast(-1); + } + + /// @brief return whether the value has a subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ + constexpr bool has_subtype() const noexcept + { + return m_has_subtype; + } + + /// @brief clears the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ + void clear_subtype() noexcept + { + m_subtype = 0; + m_has_subtype = false; + } + + private: + subtype_type m_subtype = 0; + bool m_has_subtype = false; +}; + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/abi_macros.hpp b/json-develop/include/nlohmann/detail/abi_macros.hpp new file mode 100644 index 0000000..0d3108d --- /dev/null +++ b/json-develop/include/nlohmann/detail/abi_macros.hpp @@ -0,0 +1,100 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif diff --git a/json-develop/include/nlohmann/detail/conversions/from_json.hpp b/json-develop/include/nlohmann/detail/conversions/from_json.hpp new file mode 100644 index 0000000..c6299aa --- /dev/null +++ b/json-develop/include/nlohmann/detail/conversions/from_json.hpp @@ -0,0 +1,497 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +#include +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_null())) + { + JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j)); + } + n = nullptr; +} + +// overloads for basic_json template parameters +template < typename BasicJsonType, typename ArithmeticType, + enable_if_t < std::is_arithmetic::value&& + !std::is_same::value, + int > = 0 > +void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) +{ + switch (static_cast(j)) + { + case value_t::number_unsigned: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_integer: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_float: + { + val = static_cast(*j.template get_ptr()); + break; + } + + case value_t::null: + case value_t::object: + case value_t::array: + case value_t::string: + case value_t::boolean: + case value_t::binary: + case value_t::discarded: + default: + JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j)); + } +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) + { + JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j)); + } + b = *j.template get_ptr(); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) + { + JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); + } + s = *j.template get_ptr(); +} + +template < + typename BasicJsonType, typename StringType, + enable_if_t < + std::is_assignable::value + && is_detected_exact::value + && !std::is_same::value + && !is_json_ref::value, int > = 0 > +inline void from_json(const BasicJsonType& j, StringType& s) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) + { + JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); + } + + s = *j.template get_ptr(); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) +{ + get_arithmetic_value(j, val); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) +{ + get_arithmetic_value(j, val); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) +{ + get_arithmetic_value(j, val); +} + +#if !JSON_DISABLE_ENUM_SERIALIZATION +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, EnumType& e) +{ + typename std::underlying_type::type val; + get_arithmetic_value(j, val); + e = static_cast(val); +} +#endif // JSON_DISABLE_ENUM_SERIALIZATION + +// forward_list doesn't have an insert method +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, std::forward_list& l) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + l.clear(); + std::transform(j.rbegin(), j.rend(), + std::front_inserter(l), [](const BasicJsonType & i) + { + return i.template get(); + }); +} + +// valarray doesn't have an insert method +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, std::valarray& l) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + l.resize(j.size()); + std::transform(j.begin(), j.end(), std::begin(l), + [](const BasicJsonType & elem) + { + return elem.template get(); + }); +} + +template +auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +-> decltype(j.template get(), void()) +{ + for (std::size_t i = 0; i < N; ++i) + { + arr[i] = j.at(i).template get(); + } +} + +template +inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) +{ + arr = *j.template get_ptr(); +} + +template +auto from_json_array_impl(const BasicJsonType& j, std::array& arr, + priority_tag<2> /*unused*/) +-> decltype(j.template get(), void()) +{ + for (std::size_t i = 0; i < N; ++i) + { + arr[i] = j.at(i).template get(); + } +} + +template::value, + int> = 0> +auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) +-> decltype( + arr.reserve(std::declval()), + j.template get(), + void()) +{ + using std::end; + + ConstructibleArrayType ret; + ret.reserve(j.size()); + std::transform(j.begin(), j.end(), + std::inserter(ret, end(ret)), [](const BasicJsonType & i) + { + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); + arr = std::move(ret); +} + +template::value, + int> = 0> +inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, + priority_tag<0> /*unused*/) +{ + using std::end; + + ConstructibleArrayType ret; + std::transform( + j.begin(), j.end(), std::inserter(ret, end(ret)), + [](const BasicJsonType & i) + { + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); + arr = std::move(ret); +} + +template < typename BasicJsonType, typename ConstructibleArrayType, + enable_if_t < + is_constructible_array_type::value&& + !is_constructible_object_type::value&& + !is_constructible_string_type::value&& + !std::is_same::value&& + !is_basic_json::value, + int > = 0 > +auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) +-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), +j.template get(), +void()) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + + from_json_array_impl(j, arr, priority_tag<3> {}); +} + +template < typename BasicJsonType, typename T, std::size_t... Idx > +std::array from_json_inplace_array_impl(BasicJsonType&& j, + identity_tag> /*unused*/, index_sequence /*unused*/) +{ + return { { std::forward(j).at(Idx).template get()... } }; +} + +template < typename BasicJsonType, typename T, std::size_t N > +auto from_json(BasicJsonType&& j, identity_tag> tag) +-> decltype(from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {})) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + + return from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {}); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) + { + JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j)); + } + + bin = *j.template get_ptr(); +} + +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_object())) + { + JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j)); + } + + ConstructibleObjectType ret; + const auto* inner_object = j.template get_ptr(); + using value_type = typename ConstructibleObjectType::value_type; + std::transform( + inner_object->begin(), inner_object->end(), + std::inserter(ret, ret.begin()), + [](typename BasicJsonType::object_t::value_type const & p) + { + return value_type(p.first, p.second.template get()); + }); + obj = std::move(ret); +} + +// overload for arithmetic types, not chosen for basic_json template arguments +// (BooleanType, etc..); note: Is it really necessary to provide explicit +// overloads for boolean_t etc. in case of a custom BooleanType which is not +// an arithmetic type? +template < typename BasicJsonType, typename ArithmeticType, + enable_if_t < + std::is_arithmetic::value&& + !std::is_same::value&& + !std::is_same::value&& + !std::is_same::value&& + !std::is_same::value, + int > = 0 > +inline void from_json(const BasicJsonType& j, ArithmeticType& val) +{ + switch (static_cast(j)) + { + case value_t::number_unsigned: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_integer: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_float: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::boolean: + { + val = static_cast(*j.template get_ptr()); + break; + } + + case value_t::null: + case value_t::object: + case value_t::array: + case value_t::string: + case value_t::binary: + case value_t::discarded: + default: + JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j)); + } +} + +template +std::tuple from_json_tuple_impl_base(BasicJsonType&& j, index_sequence /*unused*/) +{ + return std::make_tuple(std::forward(j).at(Idx).template get()...); +} + +template < typename BasicJsonType, class A1, class A2 > +std::pair from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<0> /*unused*/) +{ + return {std::forward(j).at(0).template get(), + std::forward(j).at(1).template get()}; +} + +template +inline void from_json_tuple_impl(BasicJsonType&& j, std::pair& p, priority_tag<1> /*unused*/) +{ + p = from_json_tuple_impl(std::forward(j), identity_tag> {}, priority_tag<0> {}); +} + +template +std::tuple from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<2> /*unused*/) +{ + return from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); +} + +template +inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple& t, priority_tag<3> /*unused*/) +{ + t = from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); +} + +template +auto from_json(BasicJsonType&& j, TupleRelated&& t) +-> decltype(from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {})) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + + return from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {}); +} + +template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, + typename = enable_if_t < !std::is_constructible < + typename BasicJsonType::string_t, Key >::value >> +inline void from_json(const BasicJsonType& j, std::map& m) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + m.clear(); + for (const auto& p : j) + { + if (JSON_HEDLEY_UNLIKELY(!p.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j)); + } + m.emplace(p.at(0).template get(), p.at(1).template get()); + } +} + +template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, + typename = enable_if_t < !std::is_constructible < + typename BasicJsonType::string_t, Key >::value >> +inline void from_json(const BasicJsonType& j, std::unordered_map& m) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + m.clear(); + for (const auto& p : j) + { + if (JSON_HEDLEY_UNLIKELY(!p.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j)); + } + m.emplace(p.at(0).template get(), p.at(1).template get()); + } +} + +#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM +template +inline void from_json(const BasicJsonType& j, std_fs::path& p) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) + { + JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); + } + p = *j.template get_ptr(); +} +#endif + +struct from_json_fn +{ + template + auto operator()(const BasicJsonType& j, T&& val) const + noexcept(noexcept(from_json(j, std::forward(val)))) + -> decltype(from_json(j, std::forward(val))) + { + return from_json(j, std::forward(val)); + } +}; + +} // namespace detail + +#ifndef JSON_HAS_CPP_17 +/// namespace to hold default `from_json` function +/// to see why this is required: +/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html +namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) +{ +#endif +JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers) + detail::static_const::value; +#ifndef JSON_HAS_CPP_17 +} // namespace +#endif + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/conversions/to_chars.hpp b/json-develop/include/nlohmann/detail/conversions/to_chars.hpp new file mode 100644 index 0000000..febef93 --- /dev/null +++ b/json-develop/include/nlohmann/detail/conversions/to_chars.hpp @@ -0,0 +1,1118 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2009 Florian Loitsch +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // signbit, isfinite +#include // intN_t, uintN_t +#include // memcpy, memmove +#include // numeric_limits +#include // conditional + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief implements the Grisu2 algorithm for binary to decimal floating-point +conversion. + +This implementation is a slightly modified version of the reference +implementation which may be obtained from +http://florian.loitsch.com/publications (bench.tar.gz). + +The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch. + +For a detailed description of the algorithm see: + +[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with + Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming + Language Design and Implementation, PLDI 2010 +[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", + Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language + Design and Implementation, PLDI 1996 +*/ +namespace dtoa_impl +{ + +template +Target reinterpret_bits(const Source source) +{ + static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); + + Target target; + std::memcpy(&target, &source, sizeof(Source)); + return target; +} + +struct diyfp // f * 2^e +{ + static constexpr int kPrecision = 64; // = q + + std::uint64_t f = 0; + int e = 0; + + constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} + + /*! + @brief returns x - y + @pre x.e == y.e and x.f >= y.f + */ + static diyfp sub(const diyfp& x, const diyfp& y) noexcept + { + JSON_ASSERT(x.e == y.e); + JSON_ASSERT(x.f >= y.f); + + return {x.f - y.f, x.e}; + } + + /*! + @brief returns x * y + @note The result is rounded. (Only the upper q bits are returned.) + */ + static diyfp mul(const diyfp& x, const diyfp& y) noexcept + { + static_assert(kPrecision == 64, "internal error"); + + // Computes: + // f = round((x.f * y.f) / 2^q) + // e = x.e + y.e + q + + // Emulate the 64-bit * 64-bit multiplication: + // + // p = u * v + // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) + // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi ) + // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 ) + // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) + // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3) + // = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) + // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) + // + // (Since Q might be larger than 2^32 - 1) + // + // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) + // + // (Q_hi + H does not overflow a 64-bit int) + // + // = p_lo + 2^64 p_hi + + const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; + const std::uint64_t u_hi = x.f >> 32u; + const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; + const std::uint64_t v_hi = y.f >> 32u; + + const std::uint64_t p0 = u_lo * v_lo; + const std::uint64_t p1 = u_lo * v_hi; + const std::uint64_t p2 = u_hi * v_lo; + const std::uint64_t p3 = u_hi * v_hi; + + const std::uint64_t p0_hi = p0 >> 32u; + const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; + const std::uint64_t p1_hi = p1 >> 32u; + const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; + const std::uint64_t p2_hi = p2 >> 32u; + + std::uint64_t Q = p0_hi + p1_lo + p2_lo; + + // The full product might now be computed as + // + // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) + // p_lo = p0_lo + (Q << 32) + // + // But in this particular case here, the full p_lo is not required. + // Effectively we only need to add the highest bit in p_lo to p_hi (and + // Q_hi + 1 does not overflow). + + Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up + + const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); + + return {h, x.e + y.e + 64}; + } + + /*! + @brief normalize x such that the significand is >= 2^(q-1) + @pre x.f != 0 + */ + static diyfp normalize(diyfp x) noexcept + { + JSON_ASSERT(x.f != 0); + + while ((x.f >> 63u) == 0) + { + x.f <<= 1u; + x.e--; + } + + return x; + } + + /*! + @brief normalize x such that the result has the exponent E + @pre e >= x.e and the upper e - x.e bits of x.f must be zero. + */ + static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept + { + const int delta = x.e - target_exponent; + + JSON_ASSERT(delta >= 0); + JSON_ASSERT(((x.f << delta) >> delta) == x.f); + + return {x.f << delta, target_exponent}; + } +}; + +struct boundaries +{ + diyfp w; + diyfp minus; + diyfp plus; +}; + +/*! +Compute the (normalized) diyfp representing the input number 'value' and its +boundaries. + +@pre value must be finite and positive +*/ +template +boundaries compute_boundaries(FloatType value) +{ + JSON_ASSERT(std::isfinite(value)); + JSON_ASSERT(value > 0); + + // Convert the IEEE representation into a diyfp. + // + // If v is denormal: + // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) + // If v is normalized: + // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) + + static_assert(std::numeric_limits::is_iec559, + "internal error: dtoa_short requires an IEEE-754 floating-point implementation"); + + constexpr int kPrecision = std::numeric_limits::digits; // = p (includes the hidden bit) + constexpr int kBias = std::numeric_limits::max_exponent - 1 + (kPrecision - 1); + constexpr int kMinExp = 1 - kBias; + constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1) + + using bits_type = typename std::conditional::type; + + const auto bits = static_cast(reinterpret_bits(value)); + const std::uint64_t E = bits >> (kPrecision - 1); + const std::uint64_t F = bits & (kHiddenBit - 1); + + const bool is_denormal = E == 0; + const diyfp v = is_denormal + ? diyfp(F, kMinExp) + : diyfp(F + kHiddenBit, static_cast(E) - kBias); + + // Compute the boundaries m- and m+ of the floating-point value + // v = f * 2^e. + // + // Determine v- and v+, the floating-point predecessor and successor if v, + // respectively. + // + // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) + // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) + // + // v+ = v + 2^e + // + // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ + // between m- and m+ round to v, regardless of how the input rounding + // algorithm breaks ties. + // + // ---+-------------+-------------+-------------+-------------+--- (A) + // v- m- v m+ v+ + // + // -----------------+------+------+-------------+-------------+--- (B) + // v- m- v m+ v+ + + const bool lower_boundary_is_closer = F == 0 && E > 1; + const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); + const diyfp m_minus = lower_boundary_is_closer + ? diyfp(4 * v.f - 1, v.e - 2) // (B) + : diyfp(2 * v.f - 1, v.e - 1); // (A) + + // Determine the normalized w+ = m+. + const diyfp w_plus = diyfp::normalize(m_plus); + + // Determine w- = m- such that e_(w-) = e_(w+). + const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); + + return {diyfp::normalize(v), w_minus, w_plus}; +} + +// Given normalized diyfp w, Grisu needs to find a (normalized) cached +// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies +// within a certain range [alpha, gamma] (Definition 3.2 from [1]) +// +// alpha <= e = e_c + e_w + q <= gamma +// +// or +// +// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q +// <= f_c * f_w * 2^gamma +// +// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies +// +// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma +// +// or +// +// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) +// +// The choice of (alpha,gamma) determines the size of the table and the form of +// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well +// in practice: +// +// The idea is to cut the number c * w = f * 2^e into two parts, which can be +// processed independently: An integral part p1, and a fractional part p2: +// +// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e +// = (f div 2^-e) + (f mod 2^-e) * 2^e +// = p1 + p2 * 2^e +// +// The conversion of p1 into decimal form requires a series of divisions and +// modulos by (a power of) 10. These operations are faster for 32-bit than for +// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be +// achieved by choosing +// +// -e >= 32 or e <= -32 := gamma +// +// In order to convert the fractional part +// +// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... +// +// into decimal form, the fraction is repeatedly multiplied by 10 and the digits +// d[-i] are extracted in order: +// +// (10 * p2) div 2^-e = d[-1] +// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... +// +// The multiplication by 10 must not overflow. It is sufficient to choose +// +// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. +// +// Since p2 = f mod 2^-e < 2^-e, +// +// -e <= 60 or e >= -60 := alpha + +constexpr int kAlpha = -60; +constexpr int kGamma = -32; + +struct cached_power // c = f * 2^e ~= 10^k +{ + std::uint64_t f; + int e; + int k; +}; + +/*! +For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached +power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c +satisfies (Definition 3.2 from [1]) + + alpha <= e_c + e + q <= gamma. +*/ +inline cached_power get_cached_power_for_binary_exponent(int e) +{ + // Now + // + // alpha <= e_c + e + q <= gamma (1) + // ==> f_c * 2^alpha <= c * 2^e * 2^q + // + // and since the c's are normalized, 2^(q-1) <= f_c, + // + // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) + // ==> 2^(alpha - e - 1) <= c + // + // If c were an exact power of ten, i.e. c = 10^k, one may determine k as + // + // k = ceil( log_10( 2^(alpha - e - 1) ) ) + // = ceil( (alpha - e - 1) * log_10(2) ) + // + // From the paper: + // "In theory the result of the procedure could be wrong since c is rounded, + // and the computation itself is approximated [...]. In practice, however, + // this simple function is sufficient." + // + // For IEEE double precision floating-point numbers converted into + // normalized diyfp's w = f * 2^e, with q = 64, + // + // e >= -1022 (min IEEE exponent) + // -52 (p - 1) + // -52 (p - 1, possibly normalize denormal IEEE numbers) + // -11 (normalize the diyfp) + // = -1137 + // + // and + // + // e <= +1023 (max IEEE exponent) + // -52 (p - 1) + // -11 (normalize the diyfp) + // = 960 + // + // This binary exponent range [-1137,960] results in a decimal exponent + // range [-307,324]. One does not need to store a cached power for each + // k in this range. For each such k it suffices to find a cached power + // such that the exponent of the product lies in [alpha,gamma]. + // This implies that the difference of the decimal exponents of adjacent + // table entries must be less than or equal to + // + // floor( (gamma - alpha) * log_10(2) ) = 8. + // + // (A smaller distance gamma-alpha would require a larger table.) + + // NB: + // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. + + constexpr int kCachedPowersMinDecExp = -300; + constexpr int kCachedPowersDecStep = 8; + + static constexpr std::array kCachedPowers = + { + { + { 0xAB70FE17C79AC6CA, -1060, -300 }, + { 0xFF77B1FCBEBCDC4F, -1034, -292 }, + { 0xBE5691EF416BD60C, -1007, -284 }, + { 0x8DD01FAD907FFC3C, -980, -276 }, + { 0xD3515C2831559A83, -954, -268 }, + { 0x9D71AC8FADA6C9B5, -927, -260 }, + { 0xEA9C227723EE8BCB, -901, -252 }, + { 0xAECC49914078536D, -874, -244 }, + { 0x823C12795DB6CE57, -847, -236 }, + { 0xC21094364DFB5637, -821, -228 }, + { 0x9096EA6F3848984F, -794, -220 }, + { 0xD77485CB25823AC7, -768, -212 }, + { 0xA086CFCD97BF97F4, -741, -204 }, + { 0xEF340A98172AACE5, -715, -196 }, + { 0xB23867FB2A35B28E, -688, -188 }, + { 0x84C8D4DFD2C63F3B, -661, -180 }, + { 0xC5DD44271AD3CDBA, -635, -172 }, + { 0x936B9FCEBB25C996, -608, -164 }, + { 0xDBAC6C247D62A584, -582, -156 }, + { 0xA3AB66580D5FDAF6, -555, -148 }, + { 0xF3E2F893DEC3F126, -529, -140 }, + { 0xB5B5ADA8AAFF80B8, -502, -132 }, + { 0x87625F056C7C4A8B, -475, -124 }, + { 0xC9BCFF6034C13053, -449, -116 }, + { 0x964E858C91BA2655, -422, -108 }, + { 0xDFF9772470297EBD, -396, -100 }, + { 0xA6DFBD9FB8E5B88F, -369, -92 }, + { 0xF8A95FCF88747D94, -343, -84 }, + { 0xB94470938FA89BCF, -316, -76 }, + { 0x8A08F0F8BF0F156B, -289, -68 }, + { 0xCDB02555653131B6, -263, -60 }, + { 0x993FE2C6D07B7FAC, -236, -52 }, + { 0xE45C10C42A2B3B06, -210, -44 }, + { 0xAA242499697392D3, -183, -36 }, + { 0xFD87B5F28300CA0E, -157, -28 }, + { 0xBCE5086492111AEB, -130, -20 }, + { 0x8CBCCC096F5088CC, -103, -12 }, + { 0xD1B71758E219652C, -77, -4 }, + { 0x9C40000000000000, -50, 4 }, + { 0xE8D4A51000000000, -24, 12 }, + { 0xAD78EBC5AC620000, 3, 20 }, + { 0x813F3978F8940984, 30, 28 }, + { 0xC097CE7BC90715B3, 56, 36 }, + { 0x8F7E32CE7BEA5C70, 83, 44 }, + { 0xD5D238A4ABE98068, 109, 52 }, + { 0x9F4F2726179A2245, 136, 60 }, + { 0xED63A231D4C4FB27, 162, 68 }, + { 0xB0DE65388CC8ADA8, 189, 76 }, + { 0x83C7088E1AAB65DB, 216, 84 }, + { 0xC45D1DF942711D9A, 242, 92 }, + { 0x924D692CA61BE758, 269, 100 }, + { 0xDA01EE641A708DEA, 295, 108 }, + { 0xA26DA3999AEF774A, 322, 116 }, + { 0xF209787BB47D6B85, 348, 124 }, + { 0xB454E4A179DD1877, 375, 132 }, + { 0x865B86925B9BC5C2, 402, 140 }, + { 0xC83553C5C8965D3D, 428, 148 }, + { 0x952AB45CFA97A0B3, 455, 156 }, + { 0xDE469FBD99A05FE3, 481, 164 }, + { 0xA59BC234DB398C25, 508, 172 }, + { 0xF6C69A72A3989F5C, 534, 180 }, + { 0xB7DCBF5354E9BECE, 561, 188 }, + { 0x88FCF317F22241E2, 588, 196 }, + { 0xCC20CE9BD35C78A5, 614, 204 }, + { 0x98165AF37B2153DF, 641, 212 }, + { 0xE2A0B5DC971F303A, 667, 220 }, + { 0xA8D9D1535CE3B396, 694, 228 }, + { 0xFB9B7CD9A4A7443C, 720, 236 }, + { 0xBB764C4CA7A44410, 747, 244 }, + { 0x8BAB8EEFB6409C1A, 774, 252 }, + { 0xD01FEF10A657842C, 800, 260 }, + { 0x9B10A4E5E9913129, 827, 268 }, + { 0xE7109BFBA19C0C9D, 853, 276 }, + { 0xAC2820D9623BF429, 880, 284 }, + { 0x80444B5E7AA7CF85, 907, 292 }, + { 0xBF21E44003ACDD2D, 933, 300 }, + { 0x8E679C2F5E44FF8F, 960, 308 }, + { 0xD433179D9C8CB841, 986, 316 }, + { 0x9E19DB92B4E31BA9, 1013, 324 }, + } + }; + + // This computation gives exactly the same results for k as + // k = ceil((kAlpha - e - 1) * 0.30102999566398114) + // for |e| <= 1500, but doesn't require floating-point operations. + // NB: log_10(2) ~= 78913 / 2^18 + JSON_ASSERT(e >= -1500); + JSON_ASSERT(e <= 1500); + const int f = kAlpha - e - 1; + const int k = (f * 78913) / (1 << 18) + static_cast(f > 0); + + const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; + JSON_ASSERT(index >= 0); + JSON_ASSERT(static_cast(index) < kCachedPowers.size()); + + const cached_power cached = kCachedPowers[static_cast(index)]; + JSON_ASSERT(kAlpha <= cached.e + e + 64); + JSON_ASSERT(kGamma >= cached.e + e + 64); + + return cached; +} + +/*! +For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. +For n == 0, returns 1 and sets pow10 := 1. +*/ +inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10) +{ + // LCOV_EXCL_START + if (n >= 1000000000) + { + pow10 = 1000000000; + return 10; + } + // LCOV_EXCL_STOP + if (n >= 100000000) + { + pow10 = 100000000; + return 9; + } + if (n >= 10000000) + { + pow10 = 10000000; + return 8; + } + if (n >= 1000000) + { + pow10 = 1000000; + return 7; + } + if (n >= 100000) + { + pow10 = 100000; + return 6; + } + if (n >= 10000) + { + pow10 = 10000; + return 5; + } + if (n >= 1000) + { + pow10 = 1000; + return 4; + } + if (n >= 100) + { + pow10 = 100; + return 3; + } + if (n >= 10) + { + pow10 = 10; + return 2; + } + + pow10 = 1; + return 1; +} + +inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, + std::uint64_t rest, std::uint64_t ten_k) +{ + JSON_ASSERT(len >= 1); + JSON_ASSERT(dist <= delta); + JSON_ASSERT(rest <= delta); + JSON_ASSERT(ten_k > 0); + + // <--------------------------- delta ----> + // <---- dist ---------> + // --------------[------------------+-------------------]-------------- + // M- w M+ + // + // ten_k + // <------> + // <---- rest ----> + // --------------[------------------+----+--------------]-------------- + // w V + // = buf * 10^k + // + // ten_k represents a unit-in-the-last-place in the decimal representation + // stored in buf. + // Decrement buf by ten_k while this takes buf closer to w. + + // The tests are written in this order to avoid overflow in unsigned + // integer arithmetic. + + while (rest < dist + && delta - rest >= ten_k + && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) + { + JSON_ASSERT(buf[len - 1] != '0'); + buf[len - 1]--; + rest += ten_k; + } +} + +/*! +Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. +M- and M+ must be normalized and share the same exponent -60 <= e <= -32. +*/ +inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, + diyfp M_minus, diyfp w, diyfp M_plus) +{ + static_assert(kAlpha >= -60, "internal error"); + static_assert(kGamma <= -32, "internal error"); + + // Generates the digits (and the exponent) of a decimal floating-point + // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's + // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma. + // + // <--------------------------- delta ----> + // <---- dist ---------> + // --------------[------------------+-------------------]-------------- + // M- w M+ + // + // Grisu2 generates the digits of M+ from left to right and stops as soon as + // V is in [M-,M+]. + + JSON_ASSERT(M_plus.e >= kAlpha); + JSON_ASSERT(M_plus.e <= kGamma); + + std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e) + std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e) + + // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): + // + // M+ = f * 2^e + // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e + // = ((p1 ) * 2^-e + (p2 )) * 2^e + // = p1 + p2 * 2^e + + const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); + + auto p1 = static_cast(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) + std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e + + // 1) + // + // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] + + JSON_ASSERT(p1 > 0); + + std::uint32_t pow10{}; + const int k = find_largest_pow10(p1, pow10); + + // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) + // + // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) + // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) + // + // M+ = p1 + p2 * 2^e + // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e + // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e + // = d[k-1] * 10^(k-1) + ( rest) * 2^e + // + // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) + // + // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] + // + // but stop as soon as + // + // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e + + int n = k; + while (n > 0) + { + // Invariants: + // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) + // pow10 = 10^(n-1) <= p1 < 10^n + // + const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) + const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) + // + // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e + // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) + // + JSON_ASSERT(d <= 9); + buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d + // + // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) + // + p1 = r; + n--; + // + // M+ = buffer * 10^n + (p1 + p2 * 2^e) + // pow10 = 10^n + // + + // Now check if enough digits have been generated. + // Compute + // + // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e + // + // Note: + // Since rest and delta share the same exponent e, it suffices to + // compare the significands. + const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; + if (rest <= delta) + { + // V = buffer * 10^n, with M- <= V <= M+. + + decimal_exponent += n; + + // We may now just stop. But instead look if the buffer could be + // decremented to bring V closer to w. + // + // pow10 = 10^n is now 1 ulp in the decimal representation V. + // The rounding procedure works with diyfp's with an implicit + // exponent of e. + // + // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e + // + const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; + grisu2_round(buffer, length, dist, delta, rest, ten_n); + + return; + } + + pow10 /= 10; + // + // pow10 = 10^(n-1) <= p1 < 10^n + // Invariants restored. + } + + // 2) + // + // The digits of the integral part have been generated: + // + // M+ = d[k-1]...d[1]d[0] + p2 * 2^e + // = buffer + p2 * 2^e + // + // Now generate the digits of the fractional part p2 * 2^e. + // + // Note: + // No decimal point is generated: the exponent is adjusted instead. + // + // p2 actually represents the fraction + // + // p2 * 2^e + // = p2 / 2^-e + // = d[-1] / 10^1 + d[-2] / 10^2 + ... + // + // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) + // + // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m + // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) + // + // using + // + // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) + // = ( d) * 2^-e + ( r) + // + // or + // 10^m * p2 * 2^e = d + r * 2^e + // + // i.e. + // + // M+ = buffer + p2 * 2^e + // = buffer + 10^-m * (d + r * 2^e) + // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e + // + // and stop as soon as 10^-m * r * 2^e <= delta * 2^e + + JSON_ASSERT(p2 > delta); + + int m = 0; + for (;;) + { + // Invariant: + // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e + // = buffer * 10^-m + 10^-m * (p2 ) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e + // + JSON_ASSERT(p2 <= (std::numeric_limits::max)() / 10); + p2 *= 10; + const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e + const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e + // + // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) + // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e + // + JSON_ASSERT(d <= 9); + buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d + // + // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e + // + p2 = r; + m++; + // + // M+ = buffer * 10^-m + 10^-m * p2 * 2^e + // Invariant restored. + + // Check if enough digits have been generated. + // + // 10^-m * p2 * 2^e <= delta * 2^e + // p2 * 2^e <= 10^m * delta * 2^e + // p2 <= 10^m * delta + delta *= 10; + dist *= 10; + if (p2 <= delta) + { + break; + } + } + + // V = buffer * 10^-m, with M- <= V <= M+. + + decimal_exponent -= m; + + // 1 ulp in the decimal representation is now 10^-m. + // Since delta and dist are now scaled by 10^m, we need to do the + // same with ulp in order to keep the units in sync. + // + // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e + // + const std::uint64_t ten_m = one.f; + grisu2_round(buffer, length, dist, delta, p2, ten_m); + + // By construction this algorithm generates the shortest possible decimal + // number (Loitsch, Theorem 6.2) which rounds back to w. + // For an input number of precision p, at least + // + // N = 1 + ceil(p * log_10(2)) + // + // decimal digits are sufficient to identify all binary floating-point + // numbers (Matula, "In-and-Out conversions"). + // This implies that the algorithm does not produce more than N decimal + // digits. + // + // N = 17 for p = 53 (IEEE double precision) + // N = 9 for p = 24 (IEEE single precision) +} + +/*! +v = buf * 10^decimal_exponent +len is the length of the buffer (number of decimal digits) +The buffer must be large enough, i.e. >= max_digits10. +*/ +JSON_HEDLEY_NON_NULL(1) +inline void grisu2(char* buf, int& len, int& decimal_exponent, + diyfp m_minus, diyfp v, diyfp m_plus) +{ + JSON_ASSERT(m_plus.e == m_minus.e); + JSON_ASSERT(m_plus.e == v.e); + + // --------(-----------------------+-----------------------)-------- (A) + // m- v m+ + // + // --------------------(-----------+-----------------------)-------- (B) + // m- v m+ + // + // First scale v (and m- and m+) such that the exponent is in the range + // [alpha, gamma]. + + const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); + + const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k + + // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] + const diyfp w = diyfp::mul(v, c_minus_k); + const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); + const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); + + // ----(---+---)---------------(---+---)---------------(---+---)---- + // w- w w+ + // = c*m- = c*v = c*m+ + // + // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and + // w+ are now off by a small amount. + // In fact: + // + // w - v * 10^k < 1 ulp + // + // To account for this inaccuracy, add resp. subtract 1 ulp. + // + // --------+---[---------------(---+---)---------------]---+-------- + // w- M- w M+ w+ + // + // Now any number in [M-, M+] (bounds included) will round to w when input, + // regardless of how the input rounding algorithm breaks ties. + // + // And digit_gen generates the shortest possible such number in [M-, M+]. + // Note that this does not mean that Grisu2 always generates the shortest + // possible number in the interval (m-, m+). + const diyfp M_minus(w_minus.f + 1, w_minus.e); + const diyfp M_plus (w_plus.f - 1, w_plus.e ); + + decimal_exponent = -cached.k; // = -(-k) = k + + grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); +} + +/*! +v = buf * 10^decimal_exponent +len is the length of the buffer (number of decimal digits) +The buffer must be large enough, i.e. >= max_digits10. +*/ +template +JSON_HEDLEY_NON_NULL(1) +void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) +{ + static_assert(diyfp::kPrecision >= std::numeric_limits::digits + 3, + "internal error: not enough precision"); + + JSON_ASSERT(std::isfinite(value)); + JSON_ASSERT(value > 0); + + // If the neighbors (and boundaries) of 'value' are always computed for double-precision + // numbers, all float's can be recovered using strtod (and strtof). However, the resulting + // decimal representations are not exactly "short". + // + // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) + // says "value is converted to a string as if by std::sprintf in the default ("C") locale" + // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars' + // does. + // On the other hand, the documentation for 'std::to_chars' requires that "parsing the + // representation using the corresponding std::from_chars function recovers value exactly". That + // indicates that single precision floating-point numbers should be recovered using + // 'std::strtof'. + // + // NB: If the neighbors are computed for single-precision numbers, there is a single float + // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision + // value is off by 1 ulp. +#if 0 + const boundaries w = compute_boundaries(static_cast(value)); +#else + const boundaries w = compute_boundaries(value); +#endif + + grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); +} + +/*! +@brief appends a decimal representation of e to buf +@return a pointer to the element following the exponent. +@pre -1000 < e < 1000 +*/ +JSON_HEDLEY_NON_NULL(1) +JSON_HEDLEY_RETURNS_NON_NULL +inline char* append_exponent(char* buf, int e) +{ + JSON_ASSERT(e > -1000); + JSON_ASSERT(e < 1000); + + if (e < 0) + { + e = -e; + *buf++ = '-'; + } + else + { + *buf++ = '+'; + } + + auto k = static_cast(e); + if (k < 10) + { + // Always print at least two digits in the exponent. + // This is for compatibility with printf("%g"). + *buf++ = '0'; + *buf++ = static_cast('0' + k); + } + else if (k < 100) + { + *buf++ = static_cast('0' + k / 10); + k %= 10; + *buf++ = static_cast('0' + k); + } + else + { + *buf++ = static_cast('0' + k / 100); + k %= 100; + *buf++ = static_cast('0' + k / 10); + k %= 10; + *buf++ = static_cast('0' + k); + } + + return buf; +} + +/*! +@brief prettify v = buf * 10^decimal_exponent + +If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point +notation. Otherwise it will be printed in exponential notation. + +@pre min_exp < 0 +@pre max_exp > 0 +*/ +JSON_HEDLEY_NON_NULL(1) +JSON_HEDLEY_RETURNS_NON_NULL +inline char* format_buffer(char* buf, int len, int decimal_exponent, + int min_exp, int max_exp) +{ + JSON_ASSERT(min_exp < 0); + JSON_ASSERT(max_exp > 0); + + const int k = len; + const int n = len + decimal_exponent; + + // v = buf * 10^(n-k) + // k is the length of the buffer (number of decimal digits) + // n is the position of the decimal point relative to the start of the buffer. + + if (k <= n && n <= max_exp) + { + // digits[000] + // len <= max_exp + 2 + + std::memset(buf + k, '0', static_cast(n) - static_cast(k)); + // Make it look like a floating-point number (#362, #378) + buf[n + 0] = '.'; + buf[n + 1] = '0'; + return buf + (static_cast(n) + 2); + } + + if (0 < n && n <= max_exp) + { + // dig.its + // len <= max_digits10 + 1 + + JSON_ASSERT(k > n); + + std::memmove(buf + (static_cast(n) + 1), buf + n, static_cast(k) - static_cast(n)); + buf[n] = '.'; + return buf + (static_cast(k) + 1U); + } + + if (min_exp < n && n <= 0) + { + // 0.[000]digits + // len <= 2 + (-min_exp - 1) + max_digits10 + + std::memmove(buf + (2 + static_cast(-n)), buf, static_cast(k)); + buf[0] = '0'; + buf[1] = '.'; + std::memset(buf + 2, '0', static_cast(-n)); + return buf + (2U + static_cast(-n) + static_cast(k)); + } + + if (k == 1) + { + // dE+123 + // len <= 1 + 5 + + buf += 1; + } + else + { + // d.igitsE+123 + // len <= max_digits10 + 1 + 5 + + std::memmove(buf + 2, buf + 1, static_cast(k) - 1); + buf[1] = '.'; + buf += 1 + static_cast(k); + } + + *buf++ = 'e'; + return append_exponent(buf, n - 1); +} + +} // namespace dtoa_impl + +/*! +@brief generates a decimal representation of the floating-point number value in [first, last). + +The format of the resulting decimal representation is similar to printf's %g +format. Returns an iterator pointing past-the-end of the decimal representation. + +@note The input number must be finite, i.e. NaN's and Inf's are not supported. +@note The buffer must be large enough. +@note The result is NOT null-terminated. +*/ +template +JSON_HEDLEY_NON_NULL(1, 2) +JSON_HEDLEY_RETURNS_NON_NULL +char* to_chars(char* first, const char* last, FloatType value) +{ + static_cast(last); // maybe unused - fix warning + JSON_ASSERT(std::isfinite(value)); + + // Use signbit(value) instead of (value < 0) since signbit works for -0. + if (std::signbit(value)) + { + value = -value; + *first++ = '-'; + } + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (value == 0) // +-0 + { + *first++ = '0'; + // Make it look like a floating-point number (#362, #378) + *first++ = '.'; + *first++ = '0'; + return first; + } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + JSON_ASSERT(last - first >= std::numeric_limits::max_digits10); + + // Compute v = buffer * 10^decimal_exponent. + // The decimal digits are stored in the buffer, which needs to be interpreted + // as an unsigned decimal integer. + // len is the length of the buffer, i.e. the number of decimal digits. + int len = 0; + int decimal_exponent = 0; + dtoa_impl::grisu2(first, len, decimal_exponent, value); + + JSON_ASSERT(len <= std::numeric_limits::max_digits10); + + // Format the buffer like printf("%.*g", prec, value) + constexpr int kMinExp = -4; + // Use digits10 here to increase compatibility with version 2. + constexpr int kMaxExp = std::numeric_limits::digits10; + + JSON_ASSERT(last - first >= kMaxExp + 2); + JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits::max_digits10); + JSON_ASSERT(last - first >= std::numeric_limits::max_digits10 + 6); + + return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/conversions/to_json.hpp b/json-develop/include/nlohmann/detail/conversions/to_json.hpp new file mode 100644 index 0000000..e70207f --- /dev/null +++ b/json-develop/include/nlohmann/detail/conversions/to_json.hpp @@ -0,0 +1,446 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // copy +#include // begin, end +#include // string +#include // tuple, get +#include // is_same, is_constructible, is_floating_point, is_enum, underlying_type +#include // move, forward, declval, pair +#include // valarray +#include // vector + +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +////////////////// +// constructors // +////////////////// + +/* + * Note all external_constructor<>::construct functions need to call + * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an + * allocated value (e.g., a string). See bug issue + * https://github.com/nlohmann/json/issues/2865 for more information. + */ + +template struct external_constructor; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::boolean; + j.m_data.m_value = b; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::string; + j.m_data.m_value = s; + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::string; + j.m_data.m_value = std::move(s); + j.assert_invariant(); + } + + template < typename BasicJsonType, typename CompatibleStringType, + enable_if_t < !std::is_same::value, + int > = 0 > + static void construct(BasicJsonType& j, const CompatibleStringType& str) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::string; + j.m_data.m_value.string = j.template create(str); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::binary; + j.m_data.m_value = typename BasicJsonType::binary_t(b); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::binary; + j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b)); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::number_float; + j.m_data.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::number_unsigned; + j.m_data.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::number_integer; + j.m_data.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = arr; + j.set_parents(); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = std::move(arr); + j.set_parents(); + j.assert_invariant(); + } + + template < typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < !std::is_same::value, + int > = 0 > + static void construct(BasicJsonType& j, const CompatibleArrayType& arr) + { + using std::begin; + using std::end; + + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value.array = j.template create(begin(arr), end(arr)); + j.set_parents(); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, const std::vector& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = value_t::array; + j.m_data.m_value.array->reserve(arr.size()); + for (const bool x : arr) + { + j.m_data.m_value.array->push_back(x); + j.set_parent(j.m_data.m_value.array->back()); + } + j.assert_invariant(); + } + + template::value, int> = 0> + static void construct(BasicJsonType& j, const std::valarray& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = value_t::array; + j.m_data.m_value.array->resize(arr.size()); + if (arr.size() > 0) + { + std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin()); + } + j.set_parents(); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::object; + j.m_data.m_value = obj; + j.set_parents(); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::object; + j.m_data.m_value = std::move(obj); + j.set_parents(); + j.assert_invariant(); + } + + template < typename BasicJsonType, typename CompatibleObjectType, + enable_if_t < !std::is_same::value, int > = 0 > + static void construct(BasicJsonType& j, const CompatibleObjectType& obj) + { + using std::begin; + using std::end; + + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::object; + j.m_data.m_value.object = j.template create(begin(obj), end(obj)); + j.set_parents(); + j.assert_invariant(); + } +}; + +///////////// +// to_json // +///////////// + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, T b) noexcept +{ + external_constructor::construct(j, b); +} + +template < typename BasicJsonType, typename BoolRef, + enable_if_t < + ((std::is_same::reference, BoolRef>::value + && !std::is_same ::reference, typename BasicJsonType::boolean_t&>::value) + || (std::is_same::const_reference, BoolRef>::value + && !std::is_same ::const_reference>, + typename BasicJsonType::boolean_t >::value)) + && std::is_convertible::value, int > = 0 > +inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept +{ + external_constructor::construct(j, static_cast(b)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, const CompatibleString& s) +{ + external_constructor::construct(j, s); +} + +template +inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) +{ + external_constructor::construct(j, std::move(s)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, FloatType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +#if !JSON_DISABLE_ENUM_SERIALIZATION +template::value, int> = 0> +inline void to_json(BasicJsonType& j, EnumType e) noexcept +{ + using underlying_type = typename std::underlying_type::type; + external_constructor::construct(j, static_cast(e)); +} +#endif // JSON_DISABLE_ENUM_SERIALIZATION + +template +inline void to_json(BasicJsonType& j, const std::vector& e) +{ + external_constructor::construct(j, e); +} + +template < typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < is_compatible_array_type::value&& + !is_compatible_object_type::value&& + !is_compatible_string_type::value&& + !std::is_same::value&& + !is_basic_json::value, + int > = 0 > +inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr) +{ + external_constructor::construct(j, arr); +} + +template +inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) +{ + external_constructor::construct(j, bin); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, const std::valarray& arr) +{ + external_constructor::construct(j, std::move(arr)); +} + +template +inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) +{ + external_constructor::construct(j, std::move(arr)); +} + +template < typename BasicJsonType, typename CompatibleObjectType, + enable_if_t < is_compatible_object_type::value&& !is_basic_json::value, int > = 0 > +inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj) +{ + external_constructor::construct(j, obj); +} + +template +inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) +{ + external_constructor::construct(j, std::move(obj)); +} + +template < + typename BasicJsonType, typename T, std::size_t N, + enable_if_t < !std::is_constructible::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + int > = 0 > +inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +{ + external_constructor::construct(j, arr); +} + +template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible::value&& std::is_constructible::value, int > = 0 > +inline void to_json(BasicJsonType& j, const std::pair& p) +{ + j = { p.first, p.second }; +} + +// for https://github.com/nlohmann/json/pull/1134 +template>::value, int> = 0> +inline void to_json(BasicJsonType& j, const T& b) +{ + j = { {b.key(), b.value()} }; +} + +template +inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) +{ + j = { std::get(t)... }; +} + +template::value, int > = 0> +inline void to_json(BasicJsonType& j, const T& t) +{ + to_json_tuple_impl(j, t, make_index_sequence::value> {}); +} + +#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM +template +inline void to_json(BasicJsonType& j, const std_fs::path& p) +{ + j = p.string(); +} +#endif + +struct to_json_fn +{ + template + auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) + -> decltype(to_json(j, std::forward(val)), void()) + { + return to_json(j, std::forward(val)); + } +}; +} // namespace detail + +#ifndef JSON_HAS_CPP_17 +/// namespace to hold default `to_json` function +/// to see why this is required: +/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html +namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) +{ +#endif +JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers) + detail::static_const::value; +#ifndef JSON_HAS_CPP_17 +} // namespace +#endif + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/exceptions.hpp b/json-develop/include/nlohmann/detail/exceptions.hpp new file mode 100644 index 0000000..23b390c --- /dev/null +++ b/json-develop/include/nlohmann/detail/exceptions.hpp @@ -0,0 +1,258 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // nullptr_t +#include // exception +#if JSON_DIAGNOSTICS + #include // accumulate +#endif +#include // runtime_error +#include // to_string +#include // vector + +#include +#include +#include +#include +#include +#include +#include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +//////////////// +// exceptions // +//////////////// + +/// @brief general exception of the @ref basic_json class +/// @sa https://json.nlohmann.me/api/basic_json/exception/ +class exception : public std::exception +{ + public: + /// returns the explanatory string + const char* what() const noexcept override + { + return m.what(); + } + + /// the id of the exception + const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) + + protected: + JSON_HEDLEY_NON_NULL(3) + exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing) + + static std::string name(const std::string& ename, int id_) + { + return concat("[json.exception.", ename, '.', std::to_string(id_), "] "); + } + + static std::string diagnostics(std::nullptr_t /*leaf_element*/) + { + return ""; + } + + template + static std::string diagnostics(const BasicJsonType* leaf_element) + { +#if JSON_DIAGNOSTICS + std::vector tokens; + for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent) + { + switch (current->m_parent->type()) + { + case value_t::array: + { + for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i) + { + if (¤t->m_parent->m_data.m_value.array->operator[](i) == current) + { + tokens.emplace_back(std::to_string(i)); + break; + } + } + break; + } + + case value_t::object: + { + for (const auto& element : *current->m_parent->m_data.m_value.object) + { + if (&element.second == current) + { + tokens.emplace_back(element.first.c_str()); + break; + } + } + break; + } + + case value_t::null: // LCOV_EXCL_LINE + case value_t::string: // LCOV_EXCL_LINE + case value_t::boolean: // LCOV_EXCL_LINE + case value_t::number_integer: // LCOV_EXCL_LINE + case value_t::number_unsigned: // LCOV_EXCL_LINE + case value_t::number_float: // LCOV_EXCL_LINE + case value_t::binary: // LCOV_EXCL_LINE + case value_t::discarded: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE + } + } + + if (tokens.empty()) + { + return ""; + } + + auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, + [](const std::string & a, const std::string & b) + { + return concat(a, '/', detail::escape(b)); + }); + return concat('(', str, ") "); +#else + static_cast(leaf_element); + return ""; +#endif + } + + private: + /// an exception object as storage for error messages + std::runtime_error m; +}; + +/// @brief exception indicating a parse error +/// @sa https://json.nlohmann.me/api/basic_json/parse_error/ +class parse_error : public exception +{ + public: + /*! + @brief create a parse error exception + @param[in] id_ the id of the exception + @param[in] pos the position where the error occurred (or with + chars_read_total=0 if the position cannot be + determined) + @param[in] what_arg the explanatory string + @return parse_error object + */ + template::value, int> = 0> + static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("parse_error", id_), "parse error", + position_string(pos), ": ", exception::diagnostics(context), what_arg); + return {id_, pos.chars_read_total, w.c_str()}; + } + + template::value, int> = 0> + static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("parse_error", id_), "parse error", + (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""), + ": ", exception::diagnostics(context), what_arg); + return {id_, byte_, w.c_str()}; + } + + /*! + @brief byte index of the parse error + + The byte index of the last read character in the input file. + + @note For an input with n bytes, 1 is the index of the first character and + n+1 is the index of the terminating null byte or the end of file. + This also holds true when reading a byte vector (CBOR or MessagePack). + */ + const std::size_t byte; + + private: + parse_error(int id_, std::size_t byte_, const char* what_arg) + : exception(id_, what_arg), byte(byte_) {} + + static std::string position_string(const position_t& pos) + { + return concat(" at line ", std::to_string(pos.lines_read + 1), + ", column ", std::to_string(pos.chars_read_current_line)); + } +}; + +/// @brief exception indicating errors with iterators +/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/ +class invalid_iterator : public exception +{ + public: + template::value, int> = 0> + static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + invalid_iterator(int id_, const char* what_arg) + : exception(id_, what_arg) {} +}; + +/// @brief exception indicating executing a member function with a wrong type +/// @sa https://json.nlohmann.me/api/basic_json/type_error/ +class type_error : public exception +{ + public: + template::value, int> = 0> + static type_error create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} +}; + +/// @brief exception indicating access out of the defined range +/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/ +class out_of_range : public exception +{ + public: + template::value, int> = 0> + static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} +}; + +/// @brief exception indicating other library errors +/// @sa https://json.nlohmann.me/api/basic_json/other_error/ +class other_error : public exception +{ + public: + template::value, int> = 0> + static other_error create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/hash.hpp b/json-develop/include/nlohmann/detail/hash.hpp new file mode 100644 index 0000000..3f05af8 --- /dev/null +++ b/json-develop/include/nlohmann/detail/hash.hpp @@ -0,0 +1,129 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // uint8_t +#include // size_t +#include // hash + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// boost::hash_combine +inline std::size_t combine(std::size_t seed, std::size_t h) noexcept +{ + seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); + return seed; +} + +/*! +@brief hash a JSON value + +The hash function tries to rely on std::hash where possible. Furthermore, the +type of the JSON value is taken into account to have different hash values for +null, 0, 0U, and false, etc. + +@tparam BasicJsonType basic_json specialization +@param j JSON value to hash +@return hash value of j +*/ +template +std::size_t hash(const BasicJsonType& j) +{ + using string_t = typename BasicJsonType::string_t; + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + + const auto type = static_cast(j.type()); + switch (j.type()) + { + case BasicJsonType::value_t::null: + case BasicJsonType::value_t::discarded: + { + return combine(type, 0); + } + + case BasicJsonType::value_t::object: + { + auto seed = combine(type, j.size()); + for (const auto& element : j.items()) + { + const auto h = std::hash {}(element.key()); + seed = combine(seed, h); + seed = combine(seed, hash(element.value())); + } + return seed; + } + + case BasicJsonType::value_t::array: + { + auto seed = combine(type, j.size()); + for (const auto& element : j) + { + seed = combine(seed, hash(element)); + } + return seed; + } + + case BasicJsonType::value_t::string: + { + const auto h = std::hash {}(j.template get_ref()); + return combine(type, h); + } + + case BasicJsonType::value_t::boolean: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_integer: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_unsigned: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_float: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::binary: + { + auto seed = combine(type, j.get_binary().size()); + const auto h = std::hash {}(j.get_binary().has_subtype()); + seed = combine(seed, h); + seed = combine(seed, static_cast(j.get_binary().subtype())); + for (const auto byte : j.get_binary()) + { + seed = combine(seed, std::hash {}(byte)); + } + return seed; + } + + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + return 0; // LCOV_EXCL_LINE + } +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/input/binary_reader.hpp b/json-develop/include/nlohmann/detail/input/binary_reader.hpp new file mode 100644 index 0000000..832c36d --- /dev/null +++ b/json-develop/include/nlohmann/detail/input/binary_reader.hpp @@ -0,0 +1,3010 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // generate_n +#include // array +#include // ldexp +#include // size_t +#include // uint8_t, uint16_t, uint32_t, uint64_t +#include // snprintf +#include // memcpy +#include // back_inserter +#include // numeric_limits +#include // char_traits, string +#include // make_pair, move +#include // vector + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// how to treat CBOR tags +enum class cbor_tag_handler_t +{ + error, ///< throw a parse_error exception in case of a tag + ignore, ///< ignore tags + store ///< store tags as binary type +}; + +/*! +@brief determine system byte order + +@return true if and only if system's byte order is little endian + +@note from https://stackoverflow.com/a/1001328/266378 +*/ +static inline bool little_endianness(int num = 1) noexcept +{ + return *reinterpret_cast(&num) == 1; +} + + +/////////////////// +// binary reader // +/////////////////// + +/*! +@brief deserialization of CBOR, MessagePack, and UBJSON values +*/ +template> +class binary_reader +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using json_sax_t = SAX; + using char_type = typename InputAdapterType::char_type; + using char_int_type = typename std::char_traits::int_type; + + public: + /*! + @brief create a binary reader + + @param[in] adapter input adapter to read from + */ + explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format) + { + (void)detail::is_sax_static_asserts {}; + } + + // make class move-only + binary_reader(const binary_reader&) = delete; + binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + binary_reader& operator=(const binary_reader&) = delete; + binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~binary_reader() = default; + + /*! + @param[in] format the binary format to parse + @param[in] sax_ a SAX event processor + @param[in] strict whether to expect the input to be consumed completed + @param[in] tag_handler how to treat CBOR tags + + @return whether parsing was successful + */ + JSON_HEDLEY_NON_NULL(3) + bool sax_parse(const input_format_t format, + json_sax_t* sax_, + const bool strict = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) + { + sax = sax_; + bool result = false; + + switch (format) + { + case input_format_t::bson: + result = parse_bson_internal(); + break; + + case input_format_t::cbor: + result = parse_cbor_internal(true, tag_handler); + break; + + case input_format_t::msgpack: + result = parse_msgpack_internal(); + break; + + case input_format_t::ubjson: + case input_format_t::bjdata: + result = parse_ubjson_internal(); + break; + + case input_format_t::json: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + } + + // strict mode: next byte must be EOF + if (result && strict) + { + if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata) + { + get_ignore_noop(); + } + else + { + get(); + } + + if (JSON_HEDLEY_UNLIKELY(current != std::char_traits::eof())) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, + exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr)); + } + } + + return result; + } + + private: + ////////// + // BSON // + ////////// + + /*! + @brief Reads in a BSON-object and passes it to the SAX-parser. + @return whether a valid BSON-value was passed to the SAX parser + */ + bool parse_bson_internal() + { + std::int32_t document_size{}; + get_number(input_format_t::bson, document_size); + + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) + { + return false; + } + + return sax->end_object(); + } + + /*! + @brief Parses a C-style string from the BSON input. + @param[in,out] result A reference to the string variable where the read + string is to be stored. + @return `true` if the \x00-byte indicating the end of the string was + encountered before the EOF; false` indicates an unexpected EOF. + */ + bool get_bson_cstr(string_t& result) + { + auto out = std::back_inserter(result); + while (true) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) + { + return false; + } + if (current == 0x00) + { + return true; + } + *out++ = static_cast(current); + } + } + + /*! + @brief Parses a zero-terminated string of length @a len from the BSON + input. + @param[in] len The length (including the zero-byte at the end) of the + string to be read. + @param[in,out] result A reference to the string variable where the read + string is to be stored. + @tparam NumberType The type of the length @a len + @pre len >= 1 + @return `true` if the string was successfully parsed + */ + template + bool get_bson_string(const NumberType len, string_t& result) + { + if (JSON_HEDLEY_UNLIKELY(len < 1)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr)); + } + + return get_string(input_format_t::bson, len - static_cast(1), result) && get() != std::char_traits::eof(); + } + + /*! + @brief Parses a byte array input of length @a len from the BSON input. + @param[in] len The length of the byte array to be read. + @param[in,out] result A reference to the binary variable where the read + array is to be stored. + @tparam NumberType The type of the length @a len + @pre len >= 0 + @return `true` if the byte array was successfully parsed + */ + template + bool get_bson_binary(const NumberType len, binary_t& result) + { + if (JSON_HEDLEY_UNLIKELY(len < 0)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr)); + } + + // All BSON binary values have a subtype + std::uint8_t subtype{}; + get_number(input_format_t::bson, subtype); + result.set_subtype(subtype); + + return get_binary(input_format_t::bson, len, result); + } + + /*! + @brief Read a BSON document element of the given @a element_type. + @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html + @param[in] element_type_parse_position The position in the input stream, + where the `element_type` was read. + @warning Not all BSON element types are supported yet. An unsupported + @a element_type will give rise to a parse_error.114: + Unsupported BSON record type 0x... + @return whether a valid BSON-object/array was passed to the SAX parser + */ + bool parse_bson_element_internal(const char_int_type element_type, + const std::size_t element_type_parse_position) + { + switch (element_type) + { + case 0x01: // double + { + double number{}; + return get_number(input_format_t::bson, number) && sax->number_float(static_cast(number), ""); + } + + case 0x02: // string + { + std::int32_t len{}; + string_t value; + return get_number(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); + } + + case 0x03: // object + { + return parse_bson_internal(); + } + + case 0x04: // array + { + return parse_bson_array(); + } + + case 0x05: // binary + { + std::int32_t len{}; + binary_t value; + return get_number(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); + } + + case 0x08: // boolean + { + return sax->boolean(get() != 0); + } + + case 0x0A: // null + { + return sax->null(); + } + + case 0x10: // int32 + { + std::int32_t value{}; + return get_number(input_format_t::bson, value) && sax->number_integer(value); + } + + case 0x12: // int64 + { + std::int64_t value{}; + return get_number(input_format_t::bson, value) && sax->number_integer(value); + } + + default: // anything else not supported (yet) + { + std::array cr{{}}; + static_cast((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + const std::string cr_str{cr.data()}; + return sax->parse_error(element_type_parse_position, cr_str, + parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr)); + } + } + } + + /*! + @brief Read a BSON element list (as specified in the BSON-spec) + + The same binary layout is used for objects and arrays, hence it must be + indicated with the argument @a is_array which one is expected + (true --> array, false --> object). + + @param[in] is_array Determines if the element list being read is to be + treated as an object (@a is_array == false), or as an + array (@a is_array == true). + @return whether a valid BSON-object/array was passed to the SAX parser + */ + bool parse_bson_element_list(const bool is_array) + { + string_t key; + + while (auto element_type = get()) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) + { + return false; + } + + const std::size_t element_type_parse_position = chars_read; + if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) + { + return false; + } + + if (!is_array && !sax->key(key)) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) + { + return false; + } + + // get_bson_cstr only appends + key.clear(); + } + + return true; + } + + /*! + @brief Reads an array from the BSON input and passes it to the SAX-parser. + @return whether a valid BSON-array was passed to the SAX parser + */ + bool parse_bson_array() + { + std::int32_t document_size{}; + get_number(input_format_t::bson, document_size); + + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) + { + return false; + } + + return sax->end_array(); + } + + ////////// + // CBOR // + ////////// + + /*! + @param[in] get_char whether a new character should be retrieved from the + input (true) or whether the last read character should + be considered instead (false) + @param[in] tag_handler how CBOR tags should be treated + + @return whether a valid CBOR value was passed to the SAX parser + */ + bool parse_cbor_internal(const bool get_char, + const cbor_tag_handler_t tag_handler) + { + switch (get_char ? get() : current) + { + // EOF + case std::char_traits::eof(): + return unexpect_eof(input_format_t::cbor, "value"); + + // Integer 0x00..0x17 (0..23) + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + return sax->number_unsigned(static_cast(current)); + + case 0x18: // Unsigned integer (one-byte uint8_t follows) + { + std::uint8_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + case 0x19: // Unsigned integer (two-byte uint16_t follows) + { + std::uint16_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + case 0x1A: // Unsigned integer (four-byte uint32_t follows) + { + std::uint32_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + case 0x1B: // Unsigned integer (eight-byte uint64_t follows) + { + std::uint64_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + // Negative integer -1-0x00..-1-0x17 (-1..-24) + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + return sax->number_integer(static_cast(0x20 - 1 - current)); + + case 0x38: // Negative integer (one-byte uint8_t follows) + { + std::uint8_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); + } + + case 0x39: // Negative integer -1-n (two-byte uint16_t follows) + { + std::uint16_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); + } + + case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) + { + std::uint32_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); + } + + case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) + { + std::uint64_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) + - static_cast(number)); + } + + // Binary data (0x00..0x17 bytes follow) + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: // Binary data (one-byte uint8_t for n follows) + case 0x59: // Binary data (two-byte uint16_t for n follow) + case 0x5A: // Binary data (four-byte uint32_t for n follow) + case 0x5B: // Binary data (eight-byte uint64_t for n follow) + case 0x5F: // Binary data (indefinite length) + { + binary_t b; + return get_cbor_binary(b) && sax->binary(b); + } + + // UTF-8 string (0x00..0x17 bytes follow) + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: // UTF-8 string (one-byte uint8_t for n follows) + case 0x79: // UTF-8 string (two-byte uint16_t for n follow) + case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) + case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) + case 0x7F: // UTF-8 string (indefinite length) + { + string_t s; + return get_cbor_string(s) && sax->string(s); + } + + // array (0x00..0x17 data items follow) + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8A: + case 0x8B: + case 0x8C: + case 0x8D: + case 0x8E: + case 0x8F: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + return get_cbor_array( + conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); + + case 0x98: // array (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); + } + + case 0x99: // array (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); + } + + case 0x9A: // array (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); + } + + case 0x9B: // array (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); + } + + case 0x9F: // array (indefinite length) + return get_cbor_array(static_cast(-1), tag_handler); + + // map (0x00..0x17 pairs of data items follow) + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + return get_cbor_object(conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); + + case 0xB8: // map (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); + } + + case 0xB9: // map (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); + } + + case 0xBA: // map (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); + } + + case 0xBB: // map (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); + } + + case 0xBF: // map (indefinite length) + return get_cbor_object(static_cast(-1), tag_handler); + + case 0xC6: // tagged item + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD8: // tagged item (1 bytes follow) + case 0xD9: // tagged item (2 bytes follow) + case 0xDA: // tagged item (4 bytes follow) + case 0xDB: // tagged item (8 bytes follow) + { + switch (tag_handler) + { + case cbor_tag_handler_t::error: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } + + case cbor_tag_handler_t::ignore: + { + // ignore binary subtype + switch (current) + { + case 0xD8: + { + std::uint8_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + case 0xD9: + { + std::uint16_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + case 0xDA: + { + std::uint32_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + case 0xDB: + { + std::uint64_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + default: + break; + } + return parse_cbor_internal(true, tag_handler); + } + + case cbor_tag_handler_t::store: + { + binary_t b; + // use binary subtype and store in binary container + switch (current) + { + case 0xD8: + { + std::uint8_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + case 0xD9: + { + std::uint16_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + case 0xDA: + { + std::uint32_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + case 0xDB: + { + std::uint64_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + default: + return parse_cbor_internal(true, tag_handler); + } + get(); + return get_cbor_binary(b) && sax->binary(b); + } + + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + return false; // LCOV_EXCL_LINE + } + } + + case 0xF4: // false + return sax->boolean(false); + + case 0xF5: // true + return sax->boolean(true); + + case 0xF6: // null + return sax->null(); + + case 0xF9: // Half-Precision Float (two-byte IEEE 754) + { + const auto byte1_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) + { + return false; + } + const auto byte2_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) + { + return false; + } + + const auto byte1 = static_cast(byte1_raw); + const auto byte2 = static_cast(byte2_raw); + + // code from RFC 7049, Appendix D, Figure 3: + // As half-precision floating-point numbers were only added + // to IEEE 754 in 2008, today's programming platforms often + // still only have limited support for them. It is very + // easy to include at least decoding support for them even + // without such support. An example of a small decoder for + // half-precision floating-point numbers in the C language + // is shown in Fig. 3. + const auto half = static_cast((byte1 << 8u) + byte2); + const double val = [&half] + { + const int exp = (half >> 10u) & 0x1Fu; + const unsigned int mant = half & 0x3FFu; + JSON_ASSERT(0 <= exp&& exp <= 32); + JSON_ASSERT(mant <= 1024); + switch (exp) + { + case 0: + return std::ldexp(mant, -24); + case 31: + return (mant == 0) + ? std::numeric_limits::infinity() + : std::numeric_limits::quiet_NaN(); + default: + return std::ldexp(mant + 1024, exp - 25); + } + }(); + return sax->number_float((half & 0x8000u) != 0 + ? static_cast(-val) + : static_cast(val), ""); + } + + case 0xFA: // Single-Precision Float (four-byte IEEE 754) + { + float number{}; + return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); + } + + case 0xFB: // Double-Precision Float (eight-byte IEEE 754) + { + double number{}; + return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); + } + + default: // anything else (0xFF is handled inside the other types) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } + } + } + + /*! + @brief reads a CBOR string + + This function first reads starting bytes to determine the expected + string length and then copies this number of bytes into a string. + Additionally, CBOR's strings with indefinite lengths are supported. + + @param[out] result created string + + @return whether string creation completed + */ + bool get_cbor_string(string_t& result) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) + { + return false; + } + + switch (current) + { + // UTF-8 string (0x00..0x17 bytes follow) + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + { + return get_string(input_format_t::cbor, static_cast(current) & 0x1Fu, result); + } + + case 0x78: // UTF-8 string (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x79: // UTF-8 string (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x7F: // UTF-8 string (indefinite length) + { + while (get() != 0xFF) + { + string_t chunk; + if (!get_cbor_string(chunk)) + { + return false; + } + result.append(chunk); + } + return true; + } + + default: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr)); + } + } + } + + /*! + @brief reads a CBOR byte array + + This function first reads starting bytes to determine the expected + byte array length and then copies this number of bytes into the byte array. + Additionally, CBOR's byte arrays with indefinite lengths are supported. + + @param[out] result created byte array + + @return whether byte array creation completed + */ + bool get_cbor_binary(binary_t& result) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) + { + return false; + } + + switch (current) + { + // Binary data (0x00..0x17 bytes follow) + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + { + return get_binary(input_format_t::cbor, static_cast(current) & 0x1Fu, result); + } + + case 0x58: // Binary data (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x59: // Binary data (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x5A: // Binary data (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x5B: // Binary data (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x5F: // Binary data (indefinite length) + { + while (get() != 0xFF) + { + binary_t chunk; + if (!get_cbor_binary(chunk)) + { + return false; + } + result.insert(result.end(), chunk.begin(), chunk.end()); + } + return true; + } + + default: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr)); + } + } + } + + /*! + @param[in] len the length of the array or static_cast(-1) for an + array of indefinite size + @param[in] tag_handler how CBOR tags should be treated + @return whether array creation completed + */ + bool get_cbor_array(const std::size_t len, + const cbor_tag_handler_t tag_handler) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) + { + return false; + } + + if (len != static_cast(-1)) + { + for (std::size_t i = 0; i < len; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) + { + return false; + } + } + } + else + { + while (get() != 0xFF) + { + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) + { + return false; + } + } + } + + return sax->end_array(); + } + + /*! + @param[in] len the length of the object or static_cast(-1) for an + object of indefinite size + @param[in] tag_handler how CBOR tags should be treated + @return whether object creation completed + */ + bool get_cbor_object(const std::size_t len, + const cbor_tag_handler_t tag_handler) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) + { + return false; + } + + if (len != 0) + { + string_t key; + if (len != static_cast(-1)) + { + for (std::size_t i = 0; i < len; ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) + { + return false; + } + key.clear(); + } + } + else + { + while (get() != 0xFF) + { + if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) + { + return false; + } + key.clear(); + } + } + } + + return sax->end_object(); + } + + ///////////// + // MsgPack // + ///////////// + + /*! + @return whether a valid MessagePack value was passed to the SAX parser + */ + bool parse_msgpack_internal() + { + switch (get()) + { + // EOF + case std::char_traits::eof(): + return unexpect_eof(input_format_t::msgpack, "value"); + + // positive fixint + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + return sax->number_unsigned(static_cast(current)); + + // fixmap + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8A: + case 0x8B: + case 0x8C: + case 0x8D: + case 0x8E: + case 0x8F: + return get_msgpack_object(conditional_static_cast(static_cast(current) & 0x0Fu)); + + // fixarray + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9A: + case 0x9B: + case 0x9C: + case 0x9D: + case 0x9E: + case 0x9F: + return get_msgpack_array(conditional_static_cast(static_cast(current) & 0x0Fu)); + + // fixstr + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + case 0xD9: // str 8 + case 0xDA: // str 16 + case 0xDB: // str 32 + { + string_t s; + return get_msgpack_string(s) && sax->string(s); + } + + case 0xC0: // nil + return sax->null(); + + case 0xC2: // false + return sax->boolean(false); + + case 0xC3: // true + return sax->boolean(true); + + case 0xC4: // bin 8 + case 0xC5: // bin 16 + case 0xC6: // bin 32 + case 0xC7: // ext 8 + case 0xC8: // ext 16 + case 0xC9: // ext 32 + case 0xD4: // fixext 1 + case 0xD5: // fixext 2 + case 0xD6: // fixext 4 + case 0xD7: // fixext 8 + case 0xD8: // fixext 16 + { + binary_t b; + return get_msgpack_binary(b) && sax->binary(b); + } + + case 0xCA: // float 32 + { + float number{}; + return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); + } + + case 0xCB: // float 64 + { + double number{}; + return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); + } + + case 0xCC: // uint 8 + { + std::uint8_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xCD: // uint 16 + { + std::uint16_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xCE: // uint 32 + { + std::uint32_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xCF: // uint 64 + { + std::uint64_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xD0: // int 8 + { + std::int8_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xD1: // int 16 + { + std::int16_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xD2: // int 32 + { + std::int32_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xD3: // int 64 + { + std::int64_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xDC: // array 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); + } + + case 0xDD: // array 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast(len)); + } + + case 0xDE: // map 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); + } + + case 0xDF: // map 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast(len)); + } + + // negative fixint + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFC: + case 0xFD: + case 0xFE: + case 0xFF: + return sax->number_integer(static_cast(current)); + + default: // anything else + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } + } + } + + /*! + @brief reads a MessagePack string + + This function first reads starting bytes to determine the expected + string length and then copies this number of bytes into a string. + + @param[out] result created string + + @return whether string creation completed + */ + bool get_msgpack_string(string_t& result) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) + { + return false; + } + + switch (current) + { + // fixstr + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + { + return get_string(input_format_t::msgpack, static_cast(current) & 0x1Fu, result); + } + + case 0xD9: // str 8 + { + std::uint8_t len{}; + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); + } + + case 0xDA: // str 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); + } + + case 0xDB: // str 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); + } + + default: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr)); + } + } + } + + /*! + @brief reads a MessagePack byte array + + This function first reads starting bytes to determine the expected + byte array length and then copies this number of bytes into a byte array. + + @param[out] result created byte array + + @return whether byte array creation completed + */ + bool get_msgpack_binary(binary_t& result) + { + // helper function to set the subtype + auto assign_and_return_true = [&result](std::int8_t subtype) + { + result.set_subtype(static_cast(subtype)); + return true; + }; + + switch (current) + { + case 0xC4: // bin 8 + { + std::uint8_t len{}; + return get_number(input_format_t::msgpack, len) && + get_binary(input_format_t::msgpack, len, result); + } + + case 0xC5: // bin 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && + get_binary(input_format_t::msgpack, len, result); + } + + case 0xC6: // bin 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && + get_binary(input_format_t::msgpack, len, result); + } + + case 0xC7: // ext 8 + { + std::uint8_t len{}; + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && + assign_and_return_true(subtype); + } + + case 0xC8: // ext 16 + { + std::uint16_t len{}; + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && + assign_and_return_true(subtype); + } + + case 0xC9: // ext 32 + { + std::uint32_t len{}; + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && + assign_and_return_true(subtype); + } + + case 0xD4: // fixext 1 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 1, result) && + assign_and_return_true(subtype); + } + + case 0xD5: // fixext 2 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 2, result) && + assign_and_return_true(subtype); + } + + case 0xD6: // fixext 4 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 4, result) && + assign_and_return_true(subtype); + } + + case 0xD7: // fixext 8 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 8, result) && + assign_and_return_true(subtype); + } + + case 0xD8: // fixext 16 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 16, result) && + assign_and_return_true(subtype); + } + + default: // LCOV_EXCL_LINE + return false; // LCOV_EXCL_LINE + } + } + + /*! + @param[in] len the length of the array + @return whether array creation completed + */ + bool get_msgpack_array(const std::size_t len) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) + { + return false; + } + + for (std::size_t i = 0; i < len; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) + { + return false; + } + } + + return sax->end_array(); + } + + /*! + @param[in] len the length of the object + @return whether object creation completed + */ + bool get_msgpack_object(const std::size_t len) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) + { + return false; + } + + string_t key; + for (std::size_t i = 0; i < len; ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) + { + return false; + } + key.clear(); + } + + return sax->end_object(); + } + + //////////// + // UBJSON // + //////////// + + /*! + @param[in] get_char whether a new character should be retrieved from the + input (true, default) or whether the last read + character should be considered instead + + @return whether a valid UBJSON value was passed to the SAX parser + */ + bool parse_ubjson_internal(const bool get_char = true) + { + return get_ubjson_value(get_char ? get_ignore_noop() : current); + } + + /*! + @brief reads a UBJSON string + + This function is either called after reading the 'S' byte explicitly + indicating a string, or in case of an object key where the 'S' byte can be + left out. + + @param[out] result created string + @param[in] get_char whether a new character should be retrieved from the + input (true, default) or whether the last read + character should be considered instead + + @return whether string creation completed + */ + bool get_ubjson_string(string_t& result, const bool get_char = true) + { + if (get_char) + { + get(); // TODO(niels): may we ignore N here? + } + + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value"))) + { + return false; + } + + switch (current) + { + case 'U': + { + std::uint8_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'i': + { + std::int8_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'I': + { + std::int16_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'l': + { + std::int32_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'L': + { + std::int64_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'u': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint16_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'm': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint32_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'M': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint64_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + default: + break; + } + auto last_token = get_token_string(); + std::string message; + + if (input_format != input_format_t::bjdata) + { + message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token; + } + else + { + message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token; + } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr)); + } + + /*! + @param[out] dim an integer vector storing the ND array dimensions + @return whether reading ND array size vector is successful + */ + bool get_ubjson_ndarray_size(std::vector& dim) + { + std::pair size_and_type; + size_t dimlen = 0; + bool no_ndarray = true; + + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray))) + { + return false; + } + + if (size_and_type.first != npos) + { + if (size_and_type.second != 0) + { + if (size_and_type.second != 'N') + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second))) + { + return false; + } + dim.push_back(dimlen); + } + } + } + else + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray))) + { + return false; + } + dim.push_back(dimlen); + } + } + } + else + { + while (current != ']') + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current))) + { + return false; + } + dim.push_back(dimlen); + get_ignore_noop(); + } + } + return true; + } + + /*! + @param[out] result determined size + @param[in,out] is_ndarray for input, `true` means already inside an ndarray vector + or ndarray dimension is not allowed; `false` means ndarray + is allowed; for output, `true` means an ndarray is found; + is_ndarray can only return `true` when its initial value + is `false` + @param[in] prefix type marker if already read, otherwise set to 0 + + @return whether size determination completed + */ + bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0) + { + if (prefix == 0) + { + prefix = get_ignore_noop(); + } + + switch (prefix) + { + case 'U': + { + std::uint8_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + result = static_cast(number); + return true; + } + + case 'i': + { + std::int8_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + result = static_cast(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char + return true; + } + + case 'I': + { + std::int16_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + result = static_cast(number); + return true; + } + + case 'l': + { + std::int32_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + result = static_cast(number); + return true; + } + + case 'L': + { + std::int64_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + if (!value_in_range_of(number)) + { + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); + } + result = static_cast(number); + return true; + } + + case 'u': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint16_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + result = static_cast(number); + return true; + } + + case 'm': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint32_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + result = conditional_static_cast(number); + return true; + } + + case 'M': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint64_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (!value_in_range_of(number)) + { + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); + } + result = detail::conditional_static_cast(number); + return true; + } + + case '[': + { + if (input_format != input_format_t::bjdata) + { + break; + } + if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr)); + } + std::vector dim; + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim))) + { + return false; + } + if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector + { + result = dim.at(dim.size() - 1); + return true; + } + if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format + { + for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container + { + if ( i == 0 ) + { + result = 0; + return true; + } + } + + string_t key = "_ArraySize_"; + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size()))) + { + return false; + } + result = 1; + for (auto i : dim) + { + result *= i; + if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type() + { + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr)); + } + if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast(i)))) + { + return false; + } + } + is_ndarray = true; + return sax->end_array(); + } + result = 0; + return true; + } + + default: + break; + } + auto last_token = get_token_string(); + std::string message; + + if (input_format != input_format_t::bjdata) + { + message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token; + } + else + { + message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token; + } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr)); + } + + /*! + @brief determine the type and size for a container + + In the optimized UBJSON format, a type and a size can be provided to allow + for a more compact representation. + + @param[out] result pair of the size and the type + @param[in] inside_ndarray whether the parser is parsing an ND array dimensional vector + + @return whether pair creation completed + */ + bool get_ubjson_size_type(std::pair& result, bool inside_ndarray = false) + { + result.first = npos; // size + result.second = 0; // type + bool is_ndarray = false; + + get_ignore_noop(); + + if (current == '$') + { + result.second = get(); // must not ignore 'N', because 'N' maybe the type + if (input_format == input_format_t::bjdata + && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second))) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr)); + } + + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type"))) + { + return false; + } + + get_ignore_noop(); + if (JSON_HEDLEY_UNLIKELY(current != '#')) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value"))) + { + return false; + } + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr)); + } + + const bool is_error = get_ubjson_size_value(result.first, is_ndarray); + if (input_format == input_format_t::bjdata && is_ndarray) + { + if (inside_ndarray) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read, + exception_message(input_format, "ndarray can not be recursive", "size"), nullptr)); + } + result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters + } + return is_error; + } + + if (current == '#') + { + const bool is_error = get_ubjson_size_value(result.first, is_ndarray); + if (input_format == input_format_t::bjdata && is_ndarray) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read, + exception_message(input_format, "ndarray requires both type and size", "size"), nullptr)); + } + return is_error; + } + + return true; + } + + /*! + @param prefix the previously read or set type prefix + @return whether value creation completed + */ + bool get_ubjson_value(const char_int_type prefix) + { + switch (prefix) + { + case std::char_traits::eof(): // EOF + return unexpect_eof(input_format, "value"); + + case 'T': // true + return sax->boolean(true); + case 'F': // false + return sax->boolean(false); + + case 'Z': // null + return sax->null(); + + case 'U': + { + std::uint8_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'i': + { + std::int8_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'I': + { + std::int16_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'l': + { + std::int32_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'L': + { + std::int64_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'u': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint16_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'm': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint32_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'M': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint64_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'h': + { + if (input_format != input_format_t::bjdata) + { + break; + } + const auto byte1_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) + { + return false; + } + const auto byte2_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) + { + return false; + } + + const auto byte1 = static_cast(byte1_raw); + const auto byte2 = static_cast(byte2_raw); + + // code from RFC 7049, Appendix D, Figure 3: + // As half-precision floating-point numbers were only added + // to IEEE 754 in 2008, today's programming platforms often + // still only have limited support for them. It is very + // easy to include at least decoding support for them even + // without such support. An example of a small decoder for + // half-precision floating-point numbers in the C language + // is shown in Fig. 3. + const auto half = static_cast((byte2 << 8u) + byte1); + const double val = [&half] + { + const int exp = (half >> 10u) & 0x1Fu; + const unsigned int mant = half & 0x3FFu; + JSON_ASSERT(0 <= exp&& exp <= 32); + JSON_ASSERT(mant <= 1024); + switch (exp) + { + case 0: + return std::ldexp(mant, -24); + case 31: + return (mant == 0) + ? std::numeric_limits::infinity() + : std::numeric_limits::quiet_NaN(); + default: + return std::ldexp(mant + 1024, exp - 25); + } + }(); + return sax->number_float((half & 0x8000u) != 0 + ? static_cast(-val) + : static_cast(val), ""); + } + + case 'd': + { + float number{}; + return get_number(input_format, number) && sax->number_float(static_cast(number), ""); + } + + case 'D': + { + double number{}; + return get_number(input_format, number) && sax->number_float(static_cast(number), ""); + } + + case 'H': + { + return get_ubjson_high_precision_number(); + } + + case 'C': // char + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char"))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(current > 127)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr)); + } + string_t s(1, static_cast(current)); + return sax->string(s); + } + + case 'S': // string + { + string_t s; + return get_ubjson_string(s) && sax->string(s); + } + + case '[': // array + return get_ubjson_array(); + + case '{': // object + return get_ubjson_object(); + + default: // anything else + break; + } + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr)); + } + + /*! + @return whether array creation completed + */ + bool get_ubjson_array() + { + std::pair size_and_type; + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) + { + return false; + } + + // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata): + // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]} + + if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0) + { + size_and_type.second &= ~(static_cast(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker + auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t) + { + return p.first < t; + }); + string_t key = "_ArrayType_"; + if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr)); + } + + string_t type = it->second; // sax->string() takes a reference + if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type))) + { + return false; + } + + if (size_and_type.second == 'C') + { + size_and_type.second = 'U'; + } + + key = "_ArrayData_"; + if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) )) + { + return false; + } + + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) + { + return false; + } + } + + return (sax->end_array() && sax->end_object()); + } + + if (size_and_type.first != npos) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) + { + return false; + } + + if (size_and_type.second != 0) + { + if (size_and_type.second != 'N') + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) + { + return false; + } + } + } + } + else + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) + { + return false; + } + } + } + } + else + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) + { + return false; + } + + while (current != ']') + { + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) + { + return false; + } + get_ignore_noop(); + } + } + + return sax->end_array(); + } + + /*! + @return whether object creation completed + */ + bool get_ubjson_object() + { + std::pair size_and_type; + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) + { + return false; + } + + // do not accept ND-array size in objects in BJData + if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr)); + } + + string_t key; + if (size_and_type.first != npos) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) + { + return false; + } + + if (size_and_type.second != 0) + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) + { + return false; + } + key.clear(); + } + } + else + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) + { + return false; + } + key.clear(); + } + } + } + else + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) + { + return false; + } + + while (current != '}') + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) + { + return false; + } + get_ignore_noop(); + key.clear(); + } + } + + return sax->end_object(); + } + + // Note, no reader for UBJSON binary types is implemented because they do + // not exist + + bool get_ubjson_high_precision_number() + { + // get size of following number string + std::size_t size{}; + bool no_ndarray = true; + auto res = get_ubjson_size_value(size, no_ndarray); + if (JSON_HEDLEY_UNLIKELY(!res)) + { + return res; + } + + // get number string + std::vector number_vector; + for (std::size_t i = 0; i < size; ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) + { + return false; + } + number_vector.push_back(static_cast(current)); + } + + // parse number string + using ia_type = decltype(detail::input_adapter(number_vector)); + auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); + const auto result_number = number_lexer.scan(); + const auto number_string = number_lexer.get_token_string(); + const auto result_remainder = number_lexer.scan(); + + using token_type = typename detail::lexer_base::token_type; + + if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) + { + return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, + exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr)); + } + + switch (result_number) + { + case token_type::value_integer: + return sax->number_integer(number_lexer.get_number_integer()); + case token_type::value_unsigned: + return sax->number_unsigned(number_lexer.get_number_unsigned()); + case token_type::value_float: + return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); + case token_type::uninitialized: + case token_type::literal_true: + case token_type::literal_false: + case token_type::literal_null: + case token_type::value_string: + case token_type::begin_array: + case token_type::begin_object: + case token_type::end_array: + case token_type::end_object: + case token_type::name_separator: + case token_type::value_separator: + case token_type::parse_error: + case token_type::end_of_input: + case token_type::literal_or_value: + default: + return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, + exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr)); + } + } + + /////////////////////// + // Utility functions // + /////////////////////// + + /*! + @brief get next character from the input + + This function provides the interface to the used input adapter. It does + not throw in case the input reached EOF, but returns a -'ve valued + `std::char_traits::eof()` in that case. + + @return character read from the input + */ + char_int_type get() + { + ++chars_read; + return current = ia.get_character(); + } + + /*! + @return character read from the input after ignoring all 'N' entries + */ + char_int_type get_ignore_noop() + { + do + { + get(); + } + while (current == 'N'); + + return current; + } + + /* + @brief read a number from the input + + @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) + @param[out] result number of type @a NumberType + + @return whether conversion completed + + @note This function needs to respect the system's endianness, because + bytes in CBOR, MessagePack, and UBJSON are stored in network order + (big endian) and therefore need reordering on little endian systems. + On the other hand, BSON and BJData use little endian and should reorder + on big endian systems. + */ + template + bool get_number(const input_format_t format, NumberType& result) + { + // step 1: read input into array with system's byte order + std::array vec{}; + for (std::size_t i = 0; i < sizeof(NumberType); ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) + { + return false; + } + + // reverse byte order prior to conversion if necessary + if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata)) + { + vec[sizeof(NumberType) - i - 1] = static_cast(current); + } + else + { + vec[i] = static_cast(current); // LCOV_EXCL_LINE + } + } + + // step 2: convert array into number of type T and return + std::memcpy(&result, vec.data(), sizeof(NumberType)); + return true; + } + + /*! + @brief create a string by reading characters from the input + + @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) + @param[in] len number of characters to read + @param[out] result string created by reading @a len bytes + + @return whether string creation completed + + @note We can not reserve @a len bytes for the result, because @a len + may be too large. Usually, @ref unexpect_eof() detects the end of + the input before we run out of string memory. + */ + template + bool get_string(const input_format_t format, + const NumberType len, + string_t& result) + { + bool success = true; + for (NumberType i = 0; i < len; i++) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) + { + success = false; + break; + } + result.push_back(static_cast(current)); + } + return success; + } + + /*! + @brief create a byte array by reading bytes from the input + + @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) + @param[in] len number of bytes to read + @param[out] result byte array created by reading @a len bytes + + @return whether byte array creation completed + + @note We can not reserve @a len bytes for the result, because @a len + may be too large. Usually, @ref unexpect_eof() detects the end of + the input before we run out of memory. + */ + template + bool get_binary(const input_format_t format, + const NumberType len, + binary_t& result) + { + bool success = true; + for (NumberType i = 0; i < len; i++) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) + { + success = false; + break; + } + result.push_back(static_cast(current)); + } + return success; + } + + /*! + @param[in] format the current format (for diagnostics) + @param[in] context further context information (for diagnostics) + @return whether the last read character is not EOF + */ + JSON_HEDLEY_NON_NULL(3) + bool unexpect_eof(const input_format_t format, const char* context) const + { + if (JSON_HEDLEY_UNLIKELY(current == std::char_traits::eof())) + { + return sax->parse_error(chars_read, "", + parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr)); + } + return true; + } + + /*! + @return a string representation of the last read byte + */ + std::string get_token_string() const + { + std::array cr{{}}; + static_cast((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + return std::string{cr.data()}; + } + + /*! + @param[in] format the current format + @param[in] detail a detailed error message + @param[in] context further context information + @return a message string to use in the parse_error exceptions + */ + std::string exception_message(const input_format_t format, + const std::string& detail, + const std::string& context) const + { + std::string error_msg = "syntax error while parsing "; + + switch (format) + { + case input_format_t::cbor: + error_msg += "CBOR"; + break; + + case input_format_t::msgpack: + error_msg += "MessagePack"; + break; + + case input_format_t::ubjson: + error_msg += "UBJSON"; + break; + + case input_format_t::bson: + error_msg += "BSON"; + break; + + case input_format_t::bjdata: + error_msg += "BJData"; + break; + + case input_format_t::json: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + } + + return concat(error_msg, ' ', context, ": ", detail); + } + + private: + static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast(-1); + + /// input adapter + InputAdapterType ia; + + /// the current character + char_int_type current = std::char_traits::eof(); + + /// the number of characters read + std::size_t chars_read = 0; + + /// whether we can assume little endianness + const bool is_little_endian = little_endianness(); + + /// input format + const input_format_t input_format = input_format_t::json; + + /// the SAX parser + json_sax_t* sax = nullptr; + + // excluded markers in bjdata optimized type +#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \ + make_array('F', 'H', 'N', 'S', 'T', 'Z', '[', '{') + +#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \ + make_array( \ + bjd_type{'C', "char"}, \ + bjd_type{'D', "double"}, \ + bjd_type{'I', "int16"}, \ + bjd_type{'L', "int64"}, \ + bjd_type{'M', "uint64"}, \ + bjd_type{'U', "uint8"}, \ + bjd_type{'d', "single"}, \ + bjd_type{'i', "int8"}, \ + bjd_type{'l', "int32"}, \ + bjd_type{'m', "uint32"}, \ + bjd_type{'u', "uint16"}) + + JSON_PRIVATE_UNLESS_TESTED: + // lookup tables + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers = + JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_; + + using bjd_type = std::pair; + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map = + JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_; + +#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ +#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr std::size_t binary_reader::npos; +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/input/input_adapters.hpp b/json-develop/include/nlohmann/detail/input/input_adapters.hpp new file mode 100644 index 0000000..cf53b1d --- /dev/null +++ b/json-develop/include/nlohmann/detail/input/input_adapters.hpp @@ -0,0 +1,494 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // size_t +#include // strlen +#include // begin, end, iterator_traits, random_access_iterator_tag, distance, next +#include // shared_ptr, make_shared, addressof +#include // accumulate +#include // string, char_traits +#include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer +#include // pair, declval + +#ifndef JSON_NO_IO + #include // FILE * + #include // istream +#endif // JSON_NO_IO + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// the supported input formats +enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata }; + +//////////////////// +// input adapters // +//////////////////// + +#ifndef JSON_NO_IO +/*! +Input adapter for stdio file access. This adapter read only 1 byte and do not use any + buffer. This adapter is a very low level adapter. +*/ +class file_input_adapter +{ + public: + using char_type = char; + + JSON_HEDLEY_NON_NULL(2) + explicit file_input_adapter(std::FILE* f) noexcept + : m_file(f) + { + JSON_ASSERT(m_file != nullptr); + } + + // make class move-only + file_input_adapter(const file_input_adapter&) = delete; + file_input_adapter(file_input_adapter&&) noexcept = default; + file_input_adapter& operator=(const file_input_adapter&) = delete; + file_input_adapter& operator=(file_input_adapter&&) = delete; + ~file_input_adapter() = default; + + std::char_traits::int_type get_character() noexcept + { + return std::fgetc(m_file); + } + + private: + /// the file pointer to read from + std::FILE* m_file; +}; + + +/*! +Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at +beginning of input. Does not support changing the underlying std::streambuf +in mid-input. Maintains underlying std::istream and std::streambuf to support +subsequent use of standard std::istream operations to process any input +characters following those used in parsing the JSON input. Clears the +std::istream flags; any input errors (e.g., EOF) will be detected by the first +subsequent call for input from the std::istream. +*/ +class input_stream_adapter +{ + public: + using char_type = char; + + ~input_stream_adapter() + { + // clear stream flags; we use underlying streambuf I/O, do not + // maintain ifstream flags, except eof + if (is != nullptr) + { + is->clear(is->rdstate() & std::ios::eofbit); + } + } + + explicit input_stream_adapter(std::istream& i) + : is(&i), sb(i.rdbuf()) + {} + + // delete because of pointer members + input_stream_adapter(const input_stream_adapter&) = delete; + input_stream_adapter& operator=(input_stream_adapter&) = delete; + input_stream_adapter& operator=(input_stream_adapter&&) = delete; + + input_stream_adapter(input_stream_adapter&& rhs) noexcept + : is(rhs.is), sb(rhs.sb) + { + rhs.is = nullptr; + rhs.sb = nullptr; + } + + // std::istream/std::streambuf use std::char_traits::to_int_type, to + // ensure that std::char_traits::eof() and the character 0xFF do not + // end up as the same value, e.g. 0xFFFFFFFF. + std::char_traits::int_type get_character() + { + auto res = sb->sbumpc(); + // set eof manually, as we don't use the istream interface. + if (JSON_HEDLEY_UNLIKELY(res == std::char_traits::eof())) + { + is->clear(is->rdstate() | std::ios::eofbit); + } + return res; + } + + private: + /// the associated input stream + std::istream* is = nullptr; + std::streambuf* sb = nullptr; +}; +#endif // JSON_NO_IO + +// General-purpose iterator-based adapter. It might not be as fast as +// theoretically possible for some containers, but it is extremely versatile. +template +class iterator_input_adapter +{ + public: + using char_type = typename std::iterator_traits::value_type; + + iterator_input_adapter(IteratorType first, IteratorType last) + : current(std::move(first)), end(std::move(last)) + {} + + typename std::char_traits::int_type get_character() + { + if (JSON_HEDLEY_LIKELY(current != end)) + { + auto result = std::char_traits::to_int_type(*current); + std::advance(current, 1); + return result; + } + + return std::char_traits::eof(); + } + + private: + IteratorType current; + IteratorType end; + + template + friend struct wide_string_input_helper; + + bool empty() const + { + return current == end; + } +}; + + +template +struct wide_string_input_helper; + +template +struct wide_string_input_helper +{ + // UTF-32 + static void fill_buffer(BaseInputAdapter& input, + std::array::int_type, 4>& utf8_bytes, + size_t& utf8_bytes_index, + size_t& utf8_bytes_filled) + { + utf8_bytes_index = 0; + + if (JSON_HEDLEY_UNLIKELY(input.empty())) + { + utf8_bytes[0] = std::char_traits::eof(); + utf8_bytes_filled = 1; + } + else + { + // get the current character + const auto wc = input.get_character(); + + // UTF-32 to UTF-8 encoding + if (wc < 0x80) + { + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + else if (wc <= 0x7FF) + { + utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u) & 0x1Fu)); + utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 2; + } + else if (wc <= 0xFFFF) + { + utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u) & 0x0Fu)); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 3; + } + else if (wc <= 0x10FFFF) + { + utf8_bytes[0] = static_cast::int_type>(0xF0u | ((static_cast(wc) >> 18u) & 0x07u)); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 12u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); + utf8_bytes[3] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 4; + } + else + { + // unknown character + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + } + } +}; + +template +struct wide_string_input_helper +{ + // UTF-16 + static void fill_buffer(BaseInputAdapter& input, + std::array::int_type, 4>& utf8_bytes, + size_t& utf8_bytes_index, + size_t& utf8_bytes_filled) + { + utf8_bytes_index = 0; + + if (JSON_HEDLEY_UNLIKELY(input.empty())) + { + utf8_bytes[0] = std::char_traits::eof(); + utf8_bytes_filled = 1; + } + else + { + // get the current character + const auto wc = input.get_character(); + + // UTF-16 to UTF-8 encoding + if (wc < 0x80) + { + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + else if (wc <= 0x7FF) + { + utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u))); + utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 2; + } + else if (0xD800 > wc || wc >= 0xE000) + { + utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u))); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 3; + } + else + { + if (JSON_HEDLEY_UNLIKELY(!input.empty())) + { + const auto wc2 = static_cast(input.get_character()); + const auto charcode = 0x10000u + (((static_cast(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); + utf8_bytes[0] = static_cast::int_type>(0xF0u | (charcode >> 18u)); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); + utf8_bytes[3] = static_cast::int_type>(0x80u | (charcode & 0x3Fu)); + utf8_bytes_filled = 4; + } + else + { + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + } + } + } +}; + +// Wraps another input apdater to convert wide character types into individual bytes. +template +class wide_string_input_adapter +{ + public: + using char_type = char; + + wide_string_input_adapter(BaseInputAdapter base) + : base_adapter(base) {} + + typename std::char_traits::int_type get_character() noexcept + { + // check if buffer needs to be filled + if (utf8_bytes_index == utf8_bytes_filled) + { + fill_buffer(); + + JSON_ASSERT(utf8_bytes_filled > 0); + JSON_ASSERT(utf8_bytes_index == 0); + } + + // use buffer + JSON_ASSERT(utf8_bytes_filled > 0); + JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); + return utf8_bytes[utf8_bytes_index++]; + } + + private: + BaseInputAdapter base_adapter; + + template + void fill_buffer() + { + wide_string_input_helper::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); + } + + /// a buffer for UTF-8 bytes + std::array::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; + + /// index to the utf8_codes array for the next valid byte + std::size_t utf8_bytes_index = 0; + /// number of valid bytes in the utf8_codes array + std::size_t utf8_bytes_filled = 0; +}; + + +template +struct iterator_input_adapter_factory +{ + using iterator_type = IteratorType; + using char_type = typename std::iterator_traits::value_type; + using adapter_type = iterator_input_adapter; + + static adapter_type create(IteratorType first, IteratorType last) + { + return adapter_type(std::move(first), std::move(last)); + } +}; + +template +struct is_iterator_of_multibyte +{ + using value_type = typename std::iterator_traits::value_type; + enum + { + value = sizeof(value_type) > 1 + }; +}; + +template +struct iterator_input_adapter_factory::value>> +{ + using iterator_type = IteratorType; + using char_type = typename std::iterator_traits::value_type; + using base_adapter_type = iterator_input_adapter; + using adapter_type = wide_string_input_adapter; + + static adapter_type create(IteratorType first, IteratorType last) + { + return adapter_type(base_adapter_type(std::move(first), std::move(last))); + } +}; + +// General purpose iterator-based input +template +typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) +{ + using factory_type = iterator_input_adapter_factory; + return factory_type::create(first, last); +} + +// Convenience shorthand from container to iterator +// Enables ADL on begin(container) and end(container) +// Encloses the using declarations in namespace for not to leak them to outside scope + +namespace container_input_adapter_factory_impl +{ + +using std::begin; +using std::end; + +template +struct container_input_adapter_factory {}; + +template +struct container_input_adapter_factory< ContainerType, + void_t()), end(std::declval()))>> + { + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + + static adapter_type create(const ContainerType& container) +{ + return input_adapter(begin(container), end(container)); +} + }; + +} // namespace container_input_adapter_factory_impl + +template +typename container_input_adapter_factory_impl::container_input_adapter_factory::adapter_type input_adapter(const ContainerType& container) +{ + return container_input_adapter_factory_impl::container_input_adapter_factory::create(container); +} + +#ifndef JSON_NO_IO +// Special cases with fast paths +inline file_input_adapter input_adapter(std::FILE* file) +{ + return file_input_adapter(file); +} + +inline input_stream_adapter input_adapter(std::istream& stream) +{ + return input_stream_adapter(stream); +} + +inline input_stream_adapter input_adapter(std::istream&& stream) +{ + return input_stream_adapter(stream); +} +#endif // JSON_NO_IO + +using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval(), std::declval())); + +// Null-delimited strings, and the like. +template < typename CharT, + typename std::enable_if < + std::is_pointer::value&& + !std::is_array::value&& + std::is_integral::type>::value&& + sizeof(typename std::remove_pointer::type) == 1, + int >::type = 0 > +contiguous_bytes_input_adapter input_adapter(CharT b) +{ + auto length = std::strlen(reinterpret_cast(b)); + const auto* ptr = reinterpret_cast(b); + return input_adapter(ptr, ptr + length); +} + +template +auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +{ + return input_adapter(array, array + N); +} + +// This class only handles inputs of input_buffer_adapter type. +// It's required so that expressions like {ptr, len} can be implicitly cast +// to the correct adapter. +class span_input_adapter +{ + public: + template < typename CharT, + typename std::enable_if < + std::is_pointer::value&& + std::is_integral::type>::value&& + sizeof(typename std::remove_pointer::type) == 1, + int >::type = 0 > + span_input_adapter(CharT b, std::size_t l) + : ia(reinterpret_cast(b), reinterpret_cast(b) + l) {} + + template::iterator_category, std::random_access_iterator_tag>::value, + int>::type = 0> + span_input_adapter(IteratorType first, IteratorType last) + : ia(input_adapter(first, last)) {} + + contiguous_bytes_input_adapter&& get() + { + return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) + } + + private: + contiguous_bytes_input_adapter ia; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/input/json_sax.hpp b/json-develop/include/nlohmann/detail/input/json_sax.hpp new file mode 100644 index 0000000..1bf46c2 --- /dev/null +++ b/json-develop/include/nlohmann/detail/input/json_sax.hpp @@ -0,0 +1,728 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include // string +#include // move +#include // vector + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/*! +@brief SAX interface + +This class describes the SAX interface used by @ref nlohmann::json::sax_parse. +Each function is called in different situations while the input is parsed. The +boolean return value informs the parser whether to continue processing the +input. +*/ +template +struct json_sax +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + + /*! + @brief a null value was read + @return whether parsing should proceed + */ + virtual bool null() = 0; + + /*! + @brief a boolean value was read + @param[in] val boolean value + @return whether parsing should proceed + */ + virtual bool boolean(bool val) = 0; + + /*! + @brief an integer number was read + @param[in] val integer value + @return whether parsing should proceed + */ + virtual bool number_integer(number_integer_t val) = 0; + + /*! + @brief an unsigned integer number was read + @param[in] val unsigned integer value + @return whether parsing should proceed + */ + virtual bool number_unsigned(number_unsigned_t val) = 0; + + /*! + @brief a floating-point number was read + @param[in] val floating-point value + @param[in] s raw token value + @return whether parsing should proceed + */ + virtual bool number_float(number_float_t val, const string_t& s) = 0; + + /*! + @brief a string value was read + @param[in] val string value + @return whether parsing should proceed + @note It is safe to move the passed string value. + */ + virtual bool string(string_t& val) = 0; + + /*! + @brief a binary value was read + @param[in] val binary value + @return whether parsing should proceed + @note It is safe to move the passed binary value. + */ + virtual bool binary(binary_t& val) = 0; + + /*! + @brief the beginning of an object was read + @param[in] elements number of object elements or -1 if unknown + @return whether parsing should proceed + @note binary formats may report the number of elements + */ + virtual bool start_object(std::size_t elements) = 0; + + /*! + @brief an object key was read + @param[in] val object key + @return whether parsing should proceed + @note It is safe to move the passed string. + */ + virtual bool key(string_t& val) = 0; + + /*! + @brief the end of an object was read + @return whether parsing should proceed + */ + virtual bool end_object() = 0; + + /*! + @brief the beginning of an array was read + @param[in] elements number of array elements or -1 if unknown + @return whether parsing should proceed + @note binary formats may report the number of elements + */ + virtual bool start_array(std::size_t elements) = 0; + + /*! + @brief the end of an array was read + @return whether parsing should proceed + */ + virtual bool end_array() = 0; + + /*! + @brief a parse error occurred + @param[in] position the position in the input where the error occurs + @param[in] last_token the last read token + @param[in] ex an exception object describing the error + @return whether parsing should proceed (must return false) + */ + virtual bool parse_error(std::size_t position, + const std::string& last_token, + const detail::exception& ex) = 0; + + json_sax() = default; + json_sax(const json_sax&) = default; + json_sax(json_sax&&) noexcept = default; + json_sax& operator=(const json_sax&) = default; + json_sax& operator=(json_sax&&) noexcept = default; + virtual ~json_sax() = default; +}; + + +namespace detail +{ +/*! +@brief SAX implementation to create a JSON value from SAX events + +This class implements the @ref json_sax interface and processes the SAX events +to create a JSON value which makes it basically a DOM parser. The structure or +hierarchy of the JSON value is managed by the stack `ref_stack` which contains +a pointer to the respective array or object for each recursion depth. + +After successful parsing, the value that is passed by reference to the +constructor contains the parsed value. + +@tparam BasicJsonType the JSON type +*/ +template +class json_sax_dom_parser +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + + /*! + @param[in,out] r reference to a JSON value that is manipulated while + parsing + @param[in] allow_exceptions_ whether parse errors yield exceptions + */ + explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) + : root(r), allow_exceptions(allow_exceptions_) + {} + + // make class move-only + json_sax_dom_parser(const json_sax_dom_parser&) = delete; + json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; + json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~json_sax_dom_parser() = default; + + bool null() + { + handle_value(nullptr); + return true; + } + + bool boolean(bool val) + { + handle_value(val); + return true; + } + + bool number_integer(number_integer_t val) + { + handle_value(val); + return true; + } + + bool number_unsigned(number_unsigned_t val) + { + handle_value(val); + return true; + } + + bool number_float(number_float_t val, const string_t& /*unused*/) + { + handle_value(val); + return true; + } + + bool string(string_t& val) + { + handle_value(val); + return true; + } + + bool binary(binary_t& val) + { + handle_value(std::move(val)); + return true; + } + + bool start_object(std::size_t len) + { + ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); + + if (JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool key(string_t& val) + { + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(ref_stack.back()->is_object()); + + // add null at given key and store the reference for later + object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val)); + return true; + } + + bool end_object() + { + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(ref_stack.back()->is_object()); + + ref_stack.back()->set_parents(); + ref_stack.pop_back(); + return true; + } + + bool start_array(std::size_t len) + { + ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); + + if (JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool end_array() + { + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(ref_stack.back()->is_array()); + + ref_stack.back()->set_parents(); + ref_stack.pop_back(); + return true; + } + + template + bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, + const Exception& ex) + { + errored = true; + static_cast(ex); + if (allow_exceptions) + { + JSON_THROW(ex); + } + return false; + } + + constexpr bool is_errored() const + { + return errored; + } + + private: + /*! + @invariant If the ref stack is empty, then the passed value will be the new + root. + @invariant If the ref stack contains a value, then it is an array or an + object to which we can add elements + */ + template + JSON_HEDLEY_RETURNS_NON_NULL + BasicJsonType* handle_value(Value&& v) + { + if (ref_stack.empty()) + { + root = BasicJsonType(std::forward(v)); + return &root; + } + + JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); + + if (ref_stack.back()->is_array()) + { + ref_stack.back()->m_data.m_value.array->emplace_back(std::forward(v)); + return &(ref_stack.back()->m_data.m_value.array->back()); + } + + JSON_ASSERT(ref_stack.back()->is_object()); + JSON_ASSERT(object_element); + *object_element = BasicJsonType(std::forward(v)); + return object_element; + } + + /// the parsed JSON value + BasicJsonType& root; + /// stack to model hierarchy of values + std::vector ref_stack {}; + /// helper to hold the reference for the next object element + BasicJsonType* object_element = nullptr; + /// whether a syntax error occurred + bool errored = false; + /// whether to throw exceptions in case of errors + const bool allow_exceptions = true; +}; + +template +class json_sax_dom_callback_parser +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using parser_callback_t = typename BasicJsonType::parser_callback_t; + using parse_event_t = typename BasicJsonType::parse_event_t; + + json_sax_dom_callback_parser(BasicJsonType& r, + const parser_callback_t cb, + const bool allow_exceptions_ = true) + : root(r), callback(cb), allow_exceptions(allow_exceptions_) + { + keep_stack.push_back(true); + } + + // make class move-only + json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; + json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; + json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~json_sax_dom_callback_parser() = default; + + bool null() + { + handle_value(nullptr); + return true; + } + + bool boolean(bool val) + { + handle_value(val); + return true; + } + + bool number_integer(number_integer_t val) + { + handle_value(val); + return true; + } + + bool number_unsigned(number_unsigned_t val) + { + handle_value(val); + return true; + } + + bool number_float(number_float_t val, const string_t& /*unused*/) + { + handle_value(val); + return true; + } + + bool string(string_t& val) + { + handle_value(val); + return true; + } + + bool binary(binary_t& val) + { + handle_value(std::move(val)); + return true; + } + + bool start_object(std::size_t len) + { + // check callback for object start + const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::object_start, discarded); + keep_stack.push_back(keep); + + auto val = handle_value(BasicJsonType::value_t::object, true); + ref_stack.push_back(val.second); + + // check object limit + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool key(string_t& val) + { + BasicJsonType k = BasicJsonType(val); + + // check callback for key + const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::key, k); + key_keep_stack.push_back(keep); + + // add discarded value at given key and store the reference for later + if (keep && ref_stack.back()) + { + object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded); + } + + return true; + } + + bool end_object() + { + if (ref_stack.back()) + { + if (!callback(static_cast(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) + { + // discard object + *ref_stack.back() = discarded; + } + else + { + ref_stack.back()->set_parents(); + } + } + + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); + ref_stack.pop_back(); + keep_stack.pop_back(); + + if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) + { + // remove discarded value + for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) + { + if (it->is_discarded()) + { + ref_stack.back()->erase(it); + break; + } + } + } + + return true; + } + + bool start_array(std::size_t len) + { + const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::array_start, discarded); + keep_stack.push_back(keep); + + auto val = handle_value(BasicJsonType::value_t::array, true); + ref_stack.push_back(val.second); + + // check array limit + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool end_array() + { + bool keep = true; + + if (ref_stack.back()) + { + keep = callback(static_cast(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); + if (keep) + { + ref_stack.back()->set_parents(); + } + else + { + // discard array + *ref_stack.back() = discarded; + } + } + + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); + ref_stack.pop_back(); + keep_stack.pop_back(); + + // remove discarded value + if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) + { + ref_stack.back()->m_data.m_value.array->pop_back(); + } + + return true; + } + + template + bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, + const Exception& ex) + { + errored = true; + static_cast(ex); + if (allow_exceptions) + { + JSON_THROW(ex); + } + return false; + } + + constexpr bool is_errored() const + { + return errored; + } + + private: + /*! + @param[in] v value to add to the JSON value we build during parsing + @param[in] skip_callback whether we should skip calling the callback + function; this is required after start_array() and + start_object() SAX events, because otherwise we would call the + callback function with an empty array or object, respectively. + + @invariant If the ref stack is empty, then the passed value will be the new + root. + @invariant If the ref stack contains a value, then it is an array or an + object to which we can add elements + + @return pair of boolean (whether value should be kept) and pointer (to the + passed value in the ref_stack hierarchy; nullptr if not kept) + */ + template + std::pair handle_value(Value&& v, const bool skip_callback = false) + { + JSON_ASSERT(!keep_stack.empty()); + + // do not handle this value if we know it would be added to a discarded + // container + if (!keep_stack.back()) + { + return {false, nullptr}; + } + + // create value + auto value = BasicJsonType(std::forward(v)); + + // check callback + const bool keep = skip_callback || callback(static_cast(ref_stack.size()), parse_event_t::value, value); + + // do not handle this value if we just learnt it shall be discarded + if (!keep) + { + return {false, nullptr}; + } + + if (ref_stack.empty()) + { + root = std::move(value); + return {true, &root}; + } + + // skip this value if we already decided to skip the parent + // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) + if (!ref_stack.back()) + { + return {false, nullptr}; + } + + // we now only expect arrays and objects + JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); + + // array + if (ref_stack.back()->is_array()) + { + ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value)); + return {true, &(ref_stack.back()->m_data.m_value.array->back())}; + } + + // object + JSON_ASSERT(ref_stack.back()->is_object()); + // check if we should store an element for the current key + JSON_ASSERT(!key_keep_stack.empty()); + const bool store_element = key_keep_stack.back(); + key_keep_stack.pop_back(); + + if (!store_element) + { + return {false, nullptr}; + } + + JSON_ASSERT(object_element); + *object_element = std::move(value); + return {true, object_element}; + } + + /// the parsed JSON value + BasicJsonType& root; + /// stack to model hierarchy of values + std::vector ref_stack {}; + /// stack to manage which values to keep + std::vector keep_stack {}; + /// stack to manage which object keys to keep + std::vector key_keep_stack {}; + /// helper to hold the reference for the next object element + BasicJsonType* object_element = nullptr; + /// whether a syntax error occurred + bool errored = false; + /// callback function + const parser_callback_t callback = nullptr; + /// whether to throw exceptions in case of errors + const bool allow_exceptions = true; + /// a discarded value for the callback + BasicJsonType discarded = BasicJsonType::value_t::discarded; +}; + +template +class json_sax_acceptor +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + + bool null() + { + return true; + } + + bool boolean(bool /*unused*/) + { + return true; + } + + bool number_integer(number_integer_t /*unused*/) + { + return true; + } + + bool number_unsigned(number_unsigned_t /*unused*/) + { + return true; + } + + bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) + { + return true; + } + + bool string(string_t& /*unused*/) + { + return true; + } + + bool binary(binary_t& /*unused*/) + { + return true; + } + + bool start_object(std::size_t /*unused*/ = static_cast(-1)) + { + return true; + } + + bool key(string_t& /*unused*/) + { + return true; + } + + bool end_object() + { + return true; + } + + bool start_array(std::size_t /*unused*/ = static_cast(-1)) + { + return true; + } + + bool end_array() + { + return true; + } + + bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) + { + return false; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/input/lexer.hpp b/json-develop/include/nlohmann/detail/input/lexer.hpp new file mode 100644 index 0000000..72e9951 --- /dev/null +++ b/json-develop/include/nlohmann/detail/input/lexer.hpp @@ -0,0 +1,1632 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // localeconv +#include // size_t +#include // snprintf +#include // strtof, strtod, strtold, strtoll, strtoull +#include // initializer_list +#include // char_traits, string +#include // move +#include // vector + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////// +// lexer // +/////////// + +template +class lexer_base +{ + public: + /// token types for the parser + enum class token_type + { + uninitialized, ///< indicating the scanner is uninitialized + literal_true, ///< the `true` literal + literal_false, ///< the `false` literal + literal_null, ///< the `null` literal + value_string, ///< a string -- use get_string() for actual value + value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value + value_integer, ///< a signed integer -- use get_number_integer() for actual value + value_float, ///< an floating point number -- use get_number_float() for actual value + begin_array, ///< the character for array begin `[` + begin_object, ///< the character for object begin `{` + end_array, ///< the character for array end `]` + end_object, ///< the character for object end `}` + name_separator, ///< the name separator `:` + value_separator, ///< the value separator `,` + parse_error, ///< indicating a parse error + end_of_input, ///< indicating the end of the input buffer + literal_or_value ///< a literal or the begin of a value (only for diagnostics) + }; + + /// return name of values of type token_type (only used for errors) + JSON_HEDLEY_RETURNS_NON_NULL + JSON_HEDLEY_CONST + static const char* token_type_name(const token_type t) noexcept + { + switch (t) + { + case token_type::uninitialized: + return ""; + case token_type::literal_true: + return "true literal"; + case token_type::literal_false: + return "false literal"; + case token_type::literal_null: + return "null literal"; + case token_type::value_string: + return "string literal"; + case token_type::value_unsigned: + case token_type::value_integer: + case token_type::value_float: + return "number literal"; + case token_type::begin_array: + return "'['"; + case token_type::begin_object: + return "'{'"; + case token_type::end_array: + return "']'"; + case token_type::end_object: + return "'}'"; + case token_type::name_separator: + return "':'"; + case token_type::value_separator: + return "','"; + case token_type::parse_error: + return ""; + case token_type::end_of_input: + return "end of input"; + case token_type::literal_or_value: + return "'[', '{', or a literal"; + // LCOV_EXCL_START + default: // catch non-enum values + return "unknown token"; + // LCOV_EXCL_STOP + } + } +}; +/*! +@brief lexical analysis + +This class organizes the lexical analysis during JSON deserialization. +*/ +template +class lexer : public lexer_base +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using char_type = typename InputAdapterType::char_type; + using char_int_type = typename std::char_traits::int_type; + + public: + using token_type = typename lexer_base::token_type; + + explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept + : ia(std::move(adapter)) + , ignore_comments(ignore_comments_) + , decimal_point_char(static_cast(get_decimal_point())) + {} + + // delete because of pointer members + lexer(const lexer&) = delete; + lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + lexer& operator=(lexer&) = delete; + lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~lexer() = default; + + private: + ///////////////////// + // locales + ///////////////////// + + /// return the locale-dependent decimal point + JSON_HEDLEY_PURE + static char get_decimal_point() noexcept + { + const auto* loc = localeconv(); + JSON_ASSERT(loc != nullptr); + return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); + } + + ///////////////////// + // scan functions + ///////////////////// + + /*! + @brief get codepoint from 4 hex characters following `\u` + + For input "\u c1 c2 c3 c4" the codepoint is: + (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 + = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) + + Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' + must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The + conversion is done by subtracting the offset (0x30, 0x37, and 0x57) + between the ASCII value of the character and the desired integer value. + + @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or + non-hex character) + */ + int get_codepoint() + { + // this function only makes sense after reading `\u` + JSON_ASSERT(current == 'u'); + int codepoint = 0; + + const auto factors = { 12u, 8u, 4u, 0u }; + for (const auto factor : factors) + { + get(); + + if (current >= '0' && current <= '9') + { + codepoint += static_cast((static_cast(current) - 0x30u) << factor); + } + else if (current >= 'A' && current <= 'F') + { + codepoint += static_cast((static_cast(current) - 0x37u) << factor); + } + else if (current >= 'a' && current <= 'f') + { + codepoint += static_cast((static_cast(current) - 0x57u) << factor); + } + else + { + return -1; + } + } + + JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF); + return codepoint; + } + + /*! + @brief check if the next byte(s) are inside a given range + + Adds the current byte and, for each passed range, reads a new byte and + checks if it is inside the range. If a violation was detected, set up an + error message and return false. Otherwise, return true. + + @param[in] ranges list of integers; interpreted as list of pairs of + inclusive lower and upper bound, respectively + + @pre The passed list @a ranges must have 2, 4, or 6 elements; that is, + 1, 2, or 3 pairs. This precondition is enforced by an assertion. + + @return true if and only if no range violation was detected + */ + bool next_byte_in_range(std::initializer_list ranges) + { + JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6); + add(current); + + for (auto range = ranges.begin(); range != ranges.end(); ++range) + { + get(); + if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) + { + add(current); + } + else + { + error_message = "invalid string: ill-formed UTF-8 byte"; + return false; + } + } + + return true; + } + + /*! + @brief scan a string literal + + This function scans a string according to Sect. 7 of RFC 8259. While + scanning, bytes are escaped and copied into buffer token_buffer. Then the + function returns successfully, token_buffer is *not* null-terminated (as it + may contain \0 bytes), and token_buffer.size() is the number of bytes in the + string. + + @return token_type::value_string if string could be successfully scanned, + token_type::parse_error otherwise + + @note In case of errors, variable error_message contains a textual + description. + */ + token_type scan_string() + { + // reset token_buffer (ignore opening quote) + reset(); + + // we entered the function by reading an open quote + JSON_ASSERT(current == '\"'); + + while (true) + { + // get next character + switch (get()) + { + // end of file while parsing string + case std::char_traits::eof(): + { + error_message = "invalid string: missing closing quote"; + return token_type::parse_error; + } + + // closing quote + case '\"': + { + return token_type::value_string; + } + + // escapes + case '\\': + { + switch (get()) + { + // quotation mark + case '\"': + add('\"'); + break; + // reverse solidus + case '\\': + add('\\'); + break; + // solidus + case '/': + add('/'); + break; + // backspace + case 'b': + add('\b'); + break; + // form feed + case 'f': + add('\f'); + break; + // line feed + case 'n': + add('\n'); + break; + // carriage return + case 'r': + add('\r'); + break; + // tab + case 't': + add('\t'); + break; + + // unicode escapes + case 'u': + { + const int codepoint1 = get_codepoint(); + int codepoint = codepoint1; // start with codepoint1 + + if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1)) + { + error_message = "invalid string: '\\u' must be followed by 4 hex digits"; + return token_type::parse_error; + } + + // check if code point is a high surrogate + if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF) + { + // expect next \uxxxx entry + if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u')) + { + const int codepoint2 = get_codepoint(); + + if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1)) + { + error_message = "invalid string: '\\u' must be followed by 4 hex digits"; + return token_type::parse_error; + } + + // check if codepoint2 is a low surrogate + if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF)) + { + // overwrite codepoint + codepoint = static_cast( + // high surrogate occupies the most significant 22 bits + (static_cast(codepoint1) << 10u) + // low surrogate occupies the least significant 15 bits + + static_cast(codepoint2) + // there is still the 0xD800, 0xDC00 and 0x10000 noise + // in the result, so we have to subtract with: + // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 + - 0x35FDC00u); + } + else + { + error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; + return token_type::parse_error; + } + } + else + { + error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; + return token_type::parse_error; + } + } + else + { + if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF)) + { + error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; + return token_type::parse_error; + } + } + + // result of the above calculation yields a proper codepoint + JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF); + + // translate codepoint into bytes + if (codepoint < 0x80) + { + // 1-byte characters: 0xxxxxxx (ASCII) + add(static_cast(codepoint)); + } + else if (codepoint <= 0x7FF) + { + // 2-byte characters: 110xxxxx 10xxxxxx + add(static_cast(0xC0u | (static_cast(codepoint) >> 6u))); + add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); + } + else if (codepoint <= 0xFFFF) + { + // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx + add(static_cast(0xE0u | (static_cast(codepoint) >> 12u))); + add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); + add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); + } + else + { + // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + add(static_cast(0xF0u | (static_cast(codepoint) >> 18u))); + add(static_cast(0x80u | ((static_cast(codepoint) >> 12u) & 0x3Fu))); + add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); + add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); + } + + break; + } + + // other characters after escape + default: + error_message = "invalid string: forbidden character after backslash"; + return token_type::parse_error; + } + + break; + } + + // invalid control characters + case 0x00: + { + error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000"; + return token_type::parse_error; + } + + case 0x01: + { + error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001"; + return token_type::parse_error; + } + + case 0x02: + { + error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002"; + return token_type::parse_error; + } + + case 0x03: + { + error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003"; + return token_type::parse_error; + } + + case 0x04: + { + error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004"; + return token_type::parse_error; + } + + case 0x05: + { + error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005"; + return token_type::parse_error; + } + + case 0x06: + { + error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006"; + return token_type::parse_error; + } + + case 0x07: + { + error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007"; + return token_type::parse_error; + } + + case 0x08: + { + error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b"; + return token_type::parse_error; + } + + case 0x09: + { + error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t"; + return token_type::parse_error; + } + + case 0x0A: + { + error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n"; + return token_type::parse_error; + } + + case 0x0B: + { + error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B"; + return token_type::parse_error; + } + + case 0x0C: + { + error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f"; + return token_type::parse_error; + } + + case 0x0D: + { + error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r"; + return token_type::parse_error; + } + + case 0x0E: + { + error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E"; + return token_type::parse_error; + } + + case 0x0F: + { + error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F"; + return token_type::parse_error; + } + + case 0x10: + { + error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010"; + return token_type::parse_error; + } + + case 0x11: + { + error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011"; + return token_type::parse_error; + } + + case 0x12: + { + error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012"; + return token_type::parse_error; + } + + case 0x13: + { + error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013"; + return token_type::parse_error; + } + + case 0x14: + { + error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014"; + return token_type::parse_error; + } + + case 0x15: + { + error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015"; + return token_type::parse_error; + } + + case 0x16: + { + error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016"; + return token_type::parse_error; + } + + case 0x17: + { + error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017"; + return token_type::parse_error; + } + + case 0x18: + { + error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018"; + return token_type::parse_error; + } + + case 0x19: + { + error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019"; + return token_type::parse_error; + } + + case 0x1A: + { + error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A"; + return token_type::parse_error; + } + + case 0x1B: + { + error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B"; + return token_type::parse_error; + } + + case 0x1C: + { + error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C"; + return token_type::parse_error; + } + + case 0x1D: + { + error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D"; + return token_type::parse_error; + } + + case 0x1E: + { + error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E"; + return token_type::parse_error; + } + + case 0x1F: + { + error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F"; + return token_type::parse_error; + } + + // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace)) + case 0x20: + case 0x21: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + { + add(current); + break; + } + + // U+0080..U+07FF: bytes C2..DF 80..BF + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + { + if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF}))) + { + return token_type::parse_error; + } + break; + } + + // U+0800..U+0FFF: bytes E0 A0..BF 80..BF + case 0xE0: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF + // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xEE: + case 0xEF: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+D000..U+D7FF: bytes ED 80..9F 80..BF + case 0xED: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF + case 0xF0: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF + case 0xF1: + case 0xF2: + case 0xF3: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF + case 0xF4: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // remaining bytes (80..C1 and F5..FF) are ill-formed + default: + { + error_message = "invalid string: ill-formed UTF-8 byte"; + return token_type::parse_error; + } + } + } + } + + /*! + * @brief scan a comment + * @return whether comment could be scanned successfully + */ + bool scan_comment() + { + switch (get()) + { + // single-line comments skip input until a newline or EOF is read + case '/': + { + while (true) + { + switch (get()) + { + case '\n': + case '\r': + case std::char_traits::eof(): + case '\0': + return true; + + default: + break; + } + } + } + + // multi-line comments skip input until */ is read + case '*': + { + while (true) + { + switch (get()) + { + case std::char_traits::eof(): + case '\0': + { + error_message = "invalid comment; missing closing '*/'"; + return false; + } + + case '*': + { + switch (get()) + { + case '/': + return true; + + default: + { + unget(); + continue; + } + } + } + + default: + continue; + } + } + } + + // unexpected character after reading '/' + default: + { + error_message = "invalid comment; expecting '/' or '*' after '/'"; + return false; + } + } + } + + JSON_HEDLEY_NON_NULL(2) + static void strtof(float& f, const char* str, char** endptr) noexcept + { + f = std::strtof(str, endptr); + } + + JSON_HEDLEY_NON_NULL(2) + static void strtof(double& f, const char* str, char** endptr) noexcept + { + f = std::strtod(str, endptr); + } + + JSON_HEDLEY_NON_NULL(2) + static void strtof(long double& f, const char* str, char** endptr) noexcept + { + f = std::strtold(str, endptr); + } + + /*! + @brief scan a number literal + + This function scans a string according to Sect. 6 of RFC 8259. + + The function is realized with a deterministic finite state machine derived + from the grammar described in RFC 8259. Starting in state "init", the + input is read and used to determined the next state. Only state "done" + accepts the number. State "error" is a trap state to model errors. In the + table below, "anything" means any character but the ones listed before. + + state | 0 | 1-9 | e E | + | - | . | anything + ---------|----------|----------|----------|---------|---------|----------|----------- + init | zero | any1 | [error] | [error] | minus | [error] | [error] + minus | zero | any1 | [error] | [error] | [error] | [error] | [error] + zero | done | done | exponent | done | done | decimal1 | done + any1 | any1 | any1 | exponent | done | done | decimal1 | done + decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error] + decimal2 | decimal2 | decimal2 | exponent | done | done | done | done + exponent | any2 | any2 | [error] | sign | sign | [error] | [error] + sign | any2 | any2 | [error] | [error] | [error] | [error] | [error] + any2 | any2 | any2 | done | done | done | done | done + + The state machine is realized with one label per state (prefixed with + "scan_number_") and `goto` statements between them. The state machine + contains cycles, but any cycle can be left when EOF is read. Therefore, + the function is guaranteed to terminate. + + During scanning, the read bytes are stored in token_buffer. This string is + then converted to a signed integer, an unsigned integer, or a + floating-point number. + + @return token_type::value_unsigned, token_type::value_integer, or + token_type::value_float if number could be successfully scanned, + token_type::parse_error otherwise + + @note The scanner is independent of the current locale. Internally, the + locale's decimal point is used instead of `.` to work with the + locale-dependent converters. + */ + token_type scan_number() // lgtm [cpp/use-of-goto] + { + // reset token_buffer to store the number's bytes + reset(); + + // the type of the parsed number; initially set to unsigned; will be + // changed if minus sign, decimal point or exponent is read + token_type number_type = token_type::value_unsigned; + + // state (init): we just found out we need to scan a number + switch (current) + { + case '-': + { + add(current); + goto scan_number_minus; + } + + case '0': + { + add(current); + goto scan_number_zero; + } + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any1; + } + + // all other characters are rejected outside scan_number() + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + } + +scan_number_minus: + // state: we just parsed a leading minus sign + number_type = token_type::value_integer; + switch (get()) + { + case '0': + { + add(current); + goto scan_number_zero; + } + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any1; + } + + default: + { + error_message = "invalid number; expected digit after '-'"; + return token_type::parse_error; + } + } + +scan_number_zero: + // state: we just parse a zero (maybe with a leading minus sign) + switch (get()) + { + case '.': + { + add(decimal_point_char); + goto scan_number_decimal1; + } + + case 'e': + case 'E': + { + add(current); + goto scan_number_exponent; + } + + default: + goto scan_number_done; + } + +scan_number_any1: + // state: we just parsed a number 0-9 (maybe with a leading minus sign) + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any1; + } + + case '.': + { + add(decimal_point_char); + goto scan_number_decimal1; + } + + case 'e': + case 'E': + { + add(current); + goto scan_number_exponent; + } + + default: + goto scan_number_done; + } + +scan_number_decimal1: + // state: we just parsed a decimal point + number_type = token_type::value_float; + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_decimal2; + } + + default: + { + error_message = "invalid number; expected digit after '.'"; + return token_type::parse_error; + } + } + +scan_number_decimal2: + // we just parsed at least one number after a decimal point + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_decimal2; + } + + case 'e': + case 'E': + { + add(current); + goto scan_number_exponent; + } + + default: + goto scan_number_done; + } + +scan_number_exponent: + // we just parsed an exponent + number_type = token_type::value_float; + switch (get()) + { + case '+': + case '-': + { + add(current); + goto scan_number_sign; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any2; + } + + default: + { + error_message = + "invalid number; expected '+', '-', or digit after exponent"; + return token_type::parse_error; + } + } + +scan_number_sign: + // we just parsed an exponent sign + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any2; + } + + default: + { + error_message = "invalid number; expected digit after exponent sign"; + return token_type::parse_error; + } + } + +scan_number_any2: + // we just parsed a number after the exponent or exponent sign + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any2; + } + + default: + goto scan_number_done; + } + +scan_number_done: + // unget the character after the number (we only read it to know that + // we are done scanning a number) + unget(); + + char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + errno = 0; + + // try to parse integers first and fall back to floats + if (number_type == token_type::value_unsigned) + { + const auto x = std::strtoull(token_buffer.data(), &endptr, 10); + + // we checked the number format before + JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); + + if (errno == 0) + { + value_unsigned = static_cast(x); + if (value_unsigned == x) + { + return token_type::value_unsigned; + } + } + } + else if (number_type == token_type::value_integer) + { + const auto x = std::strtoll(token_buffer.data(), &endptr, 10); + + // we checked the number format before + JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); + + if (errno == 0) + { + value_integer = static_cast(x); + if (value_integer == x) + { + return token_type::value_integer; + } + } + } + + // this code is reached if we parse a floating-point number or if an + // integer conversion above failed + strtof(value_float, token_buffer.data(), &endptr); + + // we checked the number format before + JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); + + return token_type::value_float; + } + + /*! + @param[in] literal_text the literal text to expect + @param[in] length the length of the passed literal text + @param[in] return_type the token type to return on success + */ + JSON_HEDLEY_NON_NULL(2) + token_type scan_literal(const char_type* literal_text, const std::size_t length, + token_type return_type) + { + JSON_ASSERT(std::char_traits::to_char_type(current) == literal_text[0]); + for (std::size_t i = 1; i < length; ++i) + { + if (JSON_HEDLEY_UNLIKELY(std::char_traits::to_char_type(get()) != literal_text[i])) + { + error_message = "invalid literal"; + return token_type::parse_error; + } + } + return return_type; + } + + ///////////////////// + // input management + ///////////////////// + + /// reset token_buffer; current character is beginning of token + void reset() noexcept + { + token_buffer.clear(); + token_string.clear(); + token_string.push_back(std::char_traits::to_char_type(current)); + } + + /* + @brief get next character from the input + + This function provides the interface to the used input adapter. It does + not throw in case the input reached EOF, but returns a + `std::char_traits::eof()` in that case. Stores the scanned characters + for use in error messages. + + @return character read from the input + */ + char_int_type get() + { + ++position.chars_read_total; + ++position.chars_read_current_line; + + if (next_unget) + { + // just reset the next_unget variable and work with current + next_unget = false; + } + else + { + current = ia.get_character(); + } + + if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) + { + token_string.push_back(std::char_traits::to_char_type(current)); + } + + if (current == '\n') + { + ++position.lines_read; + position.chars_read_current_line = 0; + } + + return current; + } + + /*! + @brief unget current character (read it again on next get) + + We implement unget by setting variable next_unget to true. The input is not + changed - we just simulate ungetting by modifying chars_read_total, + chars_read_current_line, and token_string. The next call to get() will + behave as if the unget character is read again. + */ + void unget() + { + next_unget = true; + + --position.chars_read_total; + + // in case we "unget" a newline, we have to also decrement the lines_read + if (position.chars_read_current_line == 0) + { + if (position.lines_read > 0) + { + --position.lines_read; + } + } + else + { + --position.chars_read_current_line; + } + + if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) + { + JSON_ASSERT(!token_string.empty()); + token_string.pop_back(); + } + } + + /// add a character to token_buffer + void add(char_int_type c) + { + token_buffer.push_back(static_cast(c)); + } + + public: + ///////////////////// + // value getters + ///////////////////// + + /// return integer value + constexpr number_integer_t get_number_integer() const noexcept + { + return value_integer; + } + + /// return unsigned integer value + constexpr number_unsigned_t get_number_unsigned() const noexcept + { + return value_unsigned; + } + + /// return floating-point value + constexpr number_float_t get_number_float() const noexcept + { + return value_float; + } + + /// return current string value (implicitly resets the token; useful only once) + string_t& get_string() + { + return token_buffer; + } + + ///////////////////// + // diagnostics + ///////////////////// + + /// return position of last read token + constexpr position_t get_position() const noexcept + { + return position; + } + + /// return the last read token (for errors only). Will never contain EOF + /// (an arbitrary value that is not a valid char value, often -1), because + /// 255 may legitimately occur. May contain NUL, which should be escaped. + std::string get_token_string() const + { + // escape control characters + std::string result; + for (const auto c : token_string) + { + if (static_cast(c) <= '\x1F') + { + // escape control characters + std::array cs{{}}; + static_cast((std::snprintf)(cs.data(), cs.size(), "", static_cast(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + result += cs.data(); + } + else + { + // add character as is + result.push_back(static_cast(c)); + } + } + + return result; + } + + /// return syntax error message + JSON_HEDLEY_RETURNS_NON_NULL + constexpr const char* get_error_message() const noexcept + { + return error_message; + } + + ///////////////////// + // actual scanner + ///////////////////// + + /*! + @brief skip the UTF-8 byte order mark + @return true iff there is no BOM or the correct BOM has been skipped + */ + bool skip_bom() + { + if (get() == 0xEF) + { + // check if we completely parse the BOM + return get() == 0xBB && get() == 0xBF; + } + + // the first character is not the beginning of the BOM; unget it to + // process is later + unget(); + return true; + } + + void skip_whitespace() + { + do + { + get(); + } + while (current == ' ' || current == '\t' || current == '\n' || current == '\r'); + } + + token_type scan() + { + // initially, skip the BOM + if (position.chars_read_total == 0 && !skip_bom()) + { + error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; + return token_type::parse_error; + } + + // read next character and ignore whitespace + skip_whitespace(); + + // ignore comments + while (ignore_comments && current == '/') + { + if (!scan_comment()) + { + return token_type::parse_error; + } + + // skip following whitespace + skip_whitespace(); + } + + switch (current) + { + // structural characters + case '[': + return token_type::begin_array; + case ']': + return token_type::end_array; + case '{': + return token_type::begin_object; + case '}': + return token_type::end_object; + case ':': + return token_type::name_separator; + case ',': + return token_type::value_separator; + + // literals + case 't': + { + std::array true_literal = {{static_cast('t'), static_cast('r'), static_cast('u'), static_cast('e')}}; + return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); + } + case 'f': + { + std::array false_literal = {{static_cast('f'), static_cast('a'), static_cast('l'), static_cast('s'), static_cast('e')}}; + return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); + } + case 'n': + { + std::array null_literal = {{static_cast('n'), static_cast('u'), static_cast('l'), static_cast('l')}}; + return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); + } + + // string + case '\"': + return scan_string(); + + // number + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return scan_number(); + + // end of input (the null byte is needed when parsing from + // string literals) + case '\0': + case std::char_traits::eof(): + return token_type::end_of_input; + + // error + default: + error_message = "invalid literal"; + return token_type::parse_error; + } + } + + private: + /// input adapter + InputAdapterType ia; + + /// whether comments should be ignored (true) or signaled as errors (false) + const bool ignore_comments = false; + + /// the current character + char_int_type current = std::char_traits::eof(); + + /// whether the next get() call should just return current + bool next_unget = false; + + /// the start position of the current token + position_t position {}; + + /// raw input token string (for error messages) + std::vector token_string {}; + + /// buffer for variable-length tokens (numbers, strings) + string_t token_buffer {}; + + /// a description of occurred lexer errors + const char* error_message = ""; + + // number values + number_integer_t value_integer = 0; + number_unsigned_t value_unsigned = 0; + number_float_t value_float = 0; + + /// the decimal point + const char_int_type decimal_point_char = '.'; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/input/parser.hpp b/json-develop/include/nlohmann/detail/input/parser.hpp new file mode 100644 index 0000000..8acbd4f --- /dev/null +++ b/json-develop/include/nlohmann/detail/input/parser.hpp @@ -0,0 +1,507 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // isfinite +#include // uint8_t +#include // function +#include // string +#include // move +#include // vector + +#include +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ +//////////// +// parser // +//////////// + +enum class parse_event_t : std::uint8_t +{ + /// the parser read `{` and started to process a JSON object + object_start, + /// the parser read `}` and finished processing a JSON object + object_end, + /// the parser read `[` and started to process a JSON array + array_start, + /// the parser read `]` and finished processing a JSON array + array_end, + /// the parser read a key of a value in an object + key, + /// the parser finished reading a JSON value + value +}; + +template +using parser_callback_t = + std::function; + +/*! +@brief syntax analysis + +This class implements a recursive descent parser. +*/ +template +class parser +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using lexer_t = lexer; + using token_type = typename lexer_t::token_type; + + public: + /// a parser reading from an input adapter + explicit parser(InputAdapterType&& adapter, + const parser_callback_t cb = nullptr, + const bool allow_exceptions_ = true, + const bool skip_comments = false) + : callback(cb) + , m_lexer(std::move(adapter), skip_comments) + , allow_exceptions(allow_exceptions_) + { + // read first token + get_token(); + } + + /*! + @brief public parser interface + + @param[in] strict whether to expect the last token to be EOF + @param[in,out] result parsed JSON value + + @throw parse_error.101 in case of an unexpected token + @throw parse_error.102 if to_unicode fails or surrogate error + @throw parse_error.103 if to_unicode fails + */ + void parse(const bool strict, BasicJsonType& result) + { + if (callback) + { + json_sax_dom_callback_parser sdp(result, callback, allow_exceptions); + sax_parse_internal(&sdp); + + // in strict mode, input must be completely read + if (strict && (get_token() != token_type::end_of_input)) + { + sdp.parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), + exception_message(token_type::end_of_input, "value"), nullptr)); + } + + // in case of an error, return discarded value + if (sdp.is_errored()) + { + result = value_t::discarded; + return; + } + + // set top-level value to null if it was discarded by the callback + // function + if (result.is_discarded()) + { + result = nullptr; + } + } + else + { + json_sax_dom_parser sdp(result, allow_exceptions); + sax_parse_internal(&sdp); + + // in strict mode, input must be completely read + if (strict && (get_token() != token_type::end_of_input)) + { + sdp.parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); + } + + // in case of an error, return discarded value + if (sdp.is_errored()) + { + result = value_t::discarded; + return; + } + } + + result.assert_invariant(); + } + + /*! + @brief public accept interface + + @param[in] strict whether to expect the last token to be EOF + @return whether the input is a proper JSON text + */ + bool accept(const bool strict = true) + { + json_sax_acceptor sax_acceptor; + return sax_parse(&sax_acceptor, strict); + } + + template + JSON_HEDLEY_NON_NULL(2) + bool sax_parse(SAX* sax, const bool strict = true) + { + (void)detail::is_sax_static_asserts {}; + const bool result = sax_parse_internal(sax); + + // strict mode: next byte must be EOF + if (result && strict && (get_token() != token_type::end_of_input)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); + } + + return result; + } + + private: + template + JSON_HEDLEY_NON_NULL(2) + bool sax_parse_internal(SAX* sax) + { + // stack to remember the hierarchy of structured values we are parsing + // true = array; false = object + std::vector states; + // value to avoid a goto (see comment where set to true) + bool skip_to_state_evaluation = false; + + while (true) + { + if (!skip_to_state_evaluation) + { + // invariant: get_token() was called before each iteration + switch (last_token) + { + case token_type::begin_object: + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) + { + return false; + } + + // closing } -> we are done + if (get_token() == token_type::end_object) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) + { + return false; + } + break; + } + + // parse key + if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); + } + if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) + { + return false; + } + + // parse separator (:) + if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); + } + + // remember we are now inside an object + states.push_back(false); + + // parse values + get_token(); + continue; + } + + case token_type::begin_array: + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) + { + return false; + } + + // closing ] -> we are done + if (get_token() == token_type::end_array) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) + { + return false; + } + break; + } + + // remember we are now inside an array + states.push_back(true); + + // parse values (no need to call get_token) + continue; + } + + case token_type::value_float: + { + const auto res = m_lexer.get_number_float(); + + if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr)); + } + + if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) + { + return false; + } + + break; + } + + case token_type::literal_false: + { + if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) + { + return false; + } + break; + } + + case token_type::literal_null: + { + if (JSON_HEDLEY_UNLIKELY(!sax->null())) + { + return false; + } + break; + } + + case token_type::literal_true: + { + if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) + { + return false; + } + break; + } + + case token_type::value_integer: + { + if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) + { + return false; + } + break; + } + + case token_type::value_string: + { + if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) + { + return false; + } + break; + } + + case token_type::value_unsigned: + { + if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) + { + return false; + } + break; + } + + case token_type::parse_error: + { + // using "uninitialized" to avoid "expected" message + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr)); + } + + case token_type::uninitialized: + case token_type::end_array: + case token_type::end_object: + case token_type::name_separator: + case token_type::value_separator: + case token_type::end_of_input: + case token_type::literal_or_value: + default: // the last token was unexpected + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); + } + } + } + else + { + skip_to_state_evaluation = false; + } + + // we reached this line after we successfully parsed a value + if (states.empty()) + { + // empty stack: we reached the end of the hierarchy: done + return true; + } + + if (states.back()) // array + { + // comma -> next value + if (get_token() == token_type::value_separator) + { + // parse a new value + get_token(); + continue; + } + + // closing ] + if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) + { + return false; + } + + // We are done with this array. Before we can parse a + // new value, we need to evaluate the new state first. + // By setting skip_to_state_evaluation to false, we + // are effectively jumping to the beginning of this if. + JSON_ASSERT(!states.empty()); + states.pop_back(); + skip_to_state_evaluation = true; + continue; + } + + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr)); + } + + // states.back() is false -> object + + // comma -> next value + if (get_token() == token_type::value_separator) + { + // parse key + if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); + } + + if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) + { + return false; + } + + // parse separator (:) + if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); + } + + // parse values + get_token(); + continue; + } + + // closing } + if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) + { + return false; + } + + // We are done with this object. Before we can parse a + // new value, we need to evaluate the new state first. + // By setting skip_to_state_evaluation to false, we + // are effectively jumping to the beginning of this if. + JSON_ASSERT(!states.empty()); + states.pop_back(); + skip_to_state_evaluation = true; + continue; + } + + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr)); + } + } + + /// get next token from lexer + token_type get_token() + { + return last_token = m_lexer.scan(); + } + + std::string exception_message(const token_type expected, const std::string& context) + { + std::string error_msg = "syntax error "; + + if (!context.empty()) + { + error_msg += concat("while parsing ", context, ' '); + } + + error_msg += "- "; + + if (last_token == token_type::parse_error) + { + error_msg += concat(m_lexer.get_error_message(), "; last read: '", + m_lexer.get_token_string(), '\''); + } + else + { + error_msg += concat("unexpected ", lexer_t::token_type_name(last_token)); + } + + if (expected != token_type::uninitialized) + { + error_msg += concat("; expected ", lexer_t::token_type_name(expected)); + } + + return error_msg; + } + + private: + /// callback function + const parser_callback_t callback = nullptr; + /// the type of the last read token + token_type last_token = token_type::uninitialized; + /// the lexer + lexer_t m_lexer; + /// whether to throw exceptions in case of errors + const bool allow_exceptions = true; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/input/position_t.hpp b/json-develop/include/nlohmann/detail/input/position_t.hpp new file mode 100644 index 0000000..396db0e --- /dev/null +++ b/json-develop/include/nlohmann/detail/input/position_t.hpp @@ -0,0 +1,37 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // size_t + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/iterators/internal_iterator.hpp b/json-develop/include/nlohmann/detail/iterators/internal_iterator.hpp new file mode 100644 index 0000000..13a212c --- /dev/null +++ b/json-develop/include/nlohmann/detail/iterators/internal_iterator.hpp @@ -0,0 +1,35 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief an iterator value + +@note This structure could easily be a union, but MSVC currently does not allow +unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. +*/ +template struct internal_iterator +{ + /// iterator for JSON objects + typename BasicJsonType::object_t::iterator object_iterator {}; + /// iterator for JSON arrays + typename BasicJsonType::array_t::iterator array_iterator {}; + /// generic iterator for all other types + primitive_iterator_t primitive_iterator {}; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/iterators/iter_impl.hpp b/json-develop/include/nlohmann/detail/iterators/iter_impl.hpp new file mode 100644 index 0000000..028de6e --- /dev/null +++ b/json-develop/include/nlohmann/detail/iterators/iter_impl.hpp @@ -0,0 +1,751 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next +#include // conditional, is_const, remove_const + +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// forward declare, to be able to friend it later on +template class iteration_proxy; +template class iteration_proxy_value; + +/*! +@brief a template for a bidirectional iterator for the @ref basic_json class +This class implements a both iterators (iterator and const_iterator) for the +@ref basic_json class. +@note An iterator is called *initialized* when a pointer to a JSON value has + been set (e.g., by a constructor or a copy assignment). If the iterator is + default-constructed, it is *uninitialized* and most methods are undefined. + **The library uses assertions to detect calls on uninitialized iterators.** +@requirement The class satisfies the following concept requirements: +- +[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): + The iterator that can be moved can be moved in both directions (i.e. + incremented and decremented). +@since version 1.0.0, simplified in version 2.0.9, change to bidirectional + iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) +*/ +template +class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) +{ + /// the iterator with BasicJsonType of different const-ness + using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; + /// allow basic_json to access private members + friend other_iter_impl; + friend BasicJsonType; + friend iteration_proxy; + friend iteration_proxy_value; + + using object_t = typename BasicJsonType::object_t; + using array_t = typename BasicJsonType::array_t; + // make sure BasicJsonType is basic_json or const basic_json + static_assert(is_basic_json::type>::value, + "iter_impl only accepts (const) basic_json"); + // superficial check for the LegacyBidirectionalIterator named requirement + static_assert(std::is_base_of::value + && std::is_base_of::iterator_category>::value, + "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement."); + + public: + /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. + /// The C++ Standard has never required user-defined iterators to derive from std::iterator. + /// A user-defined iterator should provide publicly accessible typedefs named + /// iterator_category, value_type, difference_type, pointer, and reference. + /// Note that value_type is required to be non-const, even for constant iterators. + using iterator_category = std::bidirectional_iterator_tag; + + /// the type of the values when the iterator is dereferenced + using value_type = typename BasicJsonType::value_type; + /// a type to represent differences between iterators + using difference_type = typename BasicJsonType::difference_type; + /// defines a pointer to the type iterated over (value_type) + using pointer = typename std::conditional::value, + typename BasicJsonType::const_pointer, + typename BasicJsonType::pointer>::type; + /// defines a reference to the type iterated over (value_type) + using reference = + typename std::conditional::value, + typename BasicJsonType::const_reference, + typename BasicJsonType::reference>::type; + + iter_impl() = default; + ~iter_impl() = default; + iter_impl(iter_impl&&) noexcept = default; + iter_impl& operator=(iter_impl&&) noexcept = default; + + /*! + @brief constructor for a given JSON instance + @param[in] object pointer to a JSON object for this iterator + @pre object != nullptr + @post The iterator is initialized; i.e. `m_object != nullptr`. + */ + explicit iter_impl(pointer object) noexcept : m_object(object) + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + m_it.object_iterator = typename object_t::iterator(); + break; + } + + case value_t::array: + { + m_it.array_iterator = typename array_t::iterator(); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator = primitive_iterator_t(); + break; + } + } + } + + /*! + @note The conventional copy constructor and copy assignment are implicitly + defined. Combined with the following converting constructor and + assignment, they support: (1) copy from iterator to iterator, (2) + copy from const iterator to const iterator, and (3) conversion from + iterator to const iterator. However conversion from const iterator + to iterator is not defined. + */ + + /*! + @brief const copy constructor + @param[in] other const iterator to copy from + @note This copy constructor had to be defined explicitly to circumvent a bug + occurring on msvc v19.0 compiler (VS 2015) debug build. For more + information refer to: https://github.com/nlohmann/json/issues/1608 + */ + iter_impl(const iter_impl& other) noexcept + : m_object(other.m_object), m_it(other.m_it) + {} + + /*! + @brief converting assignment + @param[in] other const iterator to copy from + @return const/non-const iterator + @note It is not checked whether @a other is initialized. + */ + iter_impl& operator=(const iter_impl& other) noexcept + { + if (&other != this) + { + m_object = other.m_object; + m_it = other.m_it; + } + return *this; + } + + /*! + @brief converting constructor + @param[in] other non-const iterator to copy from + @note It is not checked whether @a other is initialized. + */ + iter_impl(const iter_impl::type>& other) noexcept + : m_object(other.m_object), m_it(other.m_it) + {} + + /*! + @brief converting assignment + @param[in] other non-const iterator to copy from + @return const/non-const iterator + @note It is not checked whether @a other is initialized. + */ + iter_impl& operator=(const iter_impl::type>& other) noexcept // NOLINT(cert-oop54-cpp) + { + m_object = other.m_object; + m_it = other.m_it; + return *this; + } + + JSON_PRIVATE_UNLESS_TESTED: + /*! + @brief set the iterator to the first value + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + void set_begin() noexcept + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + m_it.object_iterator = m_object->m_data.m_value.object->begin(); + break; + } + + case value_t::array: + { + m_it.array_iterator = m_object->m_data.m_value.array->begin(); + break; + } + + case value_t::null: + { + // set to end so begin()==end() is true: null is empty + m_it.primitive_iterator.set_end(); + break; + } + + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator.set_begin(); + break; + } + } + } + + /*! + @brief set the iterator past the last value + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + void set_end() noexcept + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + m_it.object_iterator = m_object->m_data.m_value.object->end(); + break; + } + + case value_t::array: + { + m_it.array_iterator = m_object->m_data.m_value.array->end(); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator.set_end(); + break; + } + } + } + + public: + /*! + @brief return a reference to the value pointed to by the iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference operator*() const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end()); + return m_it.object_iterator->second; + } + + case value_t::array: + { + JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end()); + return *m_it.array_iterator; + } + + case value_t::null: + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) + { + return *m_object; + } + + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + } + } + } + + /*! + @brief dereference the iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + pointer operator->() const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end()); + return &(m_it.object_iterator->second); + } + + case value_t::array: + { + JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end()); + return &*m_it.array_iterator; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) + { + return m_object; + } + + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + } + } + } + + /*! + @brief post-increment (it++) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + ++(*this); + return result; + } + + /*! + @brief pre-increment (++it) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator++() + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + std::advance(m_it.object_iterator, 1); + break; + } + + case value_t::array: + { + std::advance(m_it.array_iterator, 1); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + ++m_it.primitive_iterator; + break; + } + } + + return *this; + } + + /*! + @brief post-decrement (it--) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + --(*this); + return result; + } + + /*! + @brief pre-decrement (--it) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator--() + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + std::advance(m_it.object_iterator, -1); + break; + } + + case value_t::array: + { + std::advance(m_it.array_iterator, -1); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + --m_it.primitive_iterator; + break; + } + } + + return *this; + } + + /*! + @brief comparison: equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator==(const IterImpl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object)); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + return (m_it.object_iterator == other.m_it.object_iterator); + + case value_t::array: + return (m_it.array_iterator == other.m_it.array_iterator); + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + + /*! + @brief comparison: not equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator!=(const IterImpl& other) const + { + return !operator==(other); + } + + /*! + @brief comparison: smaller + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator<(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object)); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object)); + + case value_t::array: + return (m_it.array_iterator < other.m_it.array_iterator); + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return (m_it.primitive_iterator < other.m_it.primitive_iterator); + } + } + + /*! + @brief comparison: less than or equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator<=(const iter_impl& other) const + { + return !other.operator < (*this); + } + + /*! + @brief comparison: greater than + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator>(const iter_impl& other) const + { + return !operator<=(other); + } + + /*! + @brief comparison: greater than or equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator>=(const iter_impl& other) const + { + return !operator<(other); + } + + /*! + @brief add to iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator+=(difference_type i) + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); + + case value_t::array: + { + std::advance(m_it.array_iterator, i); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator += i; + break; + } + } + + return *this; + } + + /*! + @brief subtract from iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator-=(difference_type i) + { + return operator+=(-i); + } + + /*! + @brief add to iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator+(difference_type i) const + { + auto result = *this; + result += i; + return result; + } + + /*! + @brief addition of distance and iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + friend iter_impl operator+(difference_type i, const iter_impl& it) + { + auto result = it; + result += i; + return result; + } + + /*! + @brief subtract from iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator-(difference_type i) const + { + auto result = *this; + result -= i; + return result; + } + + /*! + @brief return difference + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + difference_type operator-(const iter_impl& other) const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); + + case value_t::array: + return m_it.array_iterator - other.m_it.array_iterator; + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return m_it.primitive_iterator - other.m_it.primitive_iterator; + } + } + + /*! + @brief access to successor + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference operator[](difference_type n) const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object)); + + case value_t::array: + return *std::next(m_it.array_iterator, n); + + case value_t::null: + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) + { + return *m_object; + } + + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + } + } + } + + /*! + @brief return the key of an object iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + const typename object_t::key_type& key() const + { + JSON_ASSERT(m_object != nullptr); + + if (JSON_HEDLEY_LIKELY(m_object->is_object())) + { + return m_it.object_iterator->first; + } + + JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object)); + } + + /*! + @brief return the value of an iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference value() const + { + return operator*(); + } + + JSON_PRIVATE_UNLESS_TESTED: + /// associated JSON instance + pointer m_object = nullptr; + /// the actual iterator of the associated instance + internal_iterator::type> m_it {}; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/iterators/iteration_proxy.hpp b/json-develop/include/nlohmann/detail/iterators/iteration_proxy.hpp new file mode 100644 index 0000000..61b9420 --- /dev/null +++ b/json-develop/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -0,0 +1,242 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // size_t +#include // input_iterator_tag +#include // string, to_string +#include // tuple_size, get, tuple_element +#include // move + +#if JSON_HAS_RANGES + #include // enable_borrowed_range +#endif + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +void int_to_string( string_type& target, std::size_t value ) +{ + // For ADL + using std::to_string; + target = to_string(value); +} +template class iteration_proxy_value +{ + public: + using difference_type = std::ptrdiff_t; + using value_type = iteration_proxy_value; + using pointer = value_type *; + using reference = value_type &; + using iterator_category = std::input_iterator_tag; + using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; + + private: + /// the iterator + IteratorType anchor{}; + /// an index for arrays (used to create key names) + std::size_t array_index = 0; + /// last stringified array index + mutable std::size_t array_index_last = 0; + /// a string representation of the array index + mutable string_type array_index_str = "0"; + /// an empty string (to return a reference for primitive values) + string_type empty_str{}; + + public: + explicit iteration_proxy_value() = default; + explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0) + noexcept(std::is_nothrow_move_constructible::value + && std::is_nothrow_default_constructible::value) + : anchor(std::move(it)) + , array_index(array_index_) + {} + + iteration_proxy_value(iteration_proxy_value const&) = default; + iteration_proxy_value& operator=(iteration_proxy_value const&) = default; + // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions + iteration_proxy_value(iteration_proxy_value&&) + noexcept(std::is_nothrow_move_constructible::value + && std::is_nothrow_move_constructible::value) = default; + iteration_proxy_value& operator=(iteration_proxy_value&&) + noexcept(std::is_nothrow_move_assignable::value + && std::is_nothrow_move_assignable::value) = default; + ~iteration_proxy_value() = default; + + /// dereference operator (needed for range-based for) + const iteration_proxy_value& operator*() const + { + return *this; + } + + /// increment operator (needed for range-based for) + iteration_proxy_value& operator++() + { + ++anchor; + ++array_index; + + return *this; + } + + iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp) + { + auto tmp = iteration_proxy_value(anchor, array_index); + ++anchor; + ++array_index; + return tmp; + } + + /// equality operator (needed for InputIterator) + bool operator==(const iteration_proxy_value& o) const + { + return anchor == o.anchor; + } + + /// inequality operator (needed for range-based for) + bool operator!=(const iteration_proxy_value& o) const + { + return anchor != o.anchor; + } + + /// return key of the iterator + const string_type& key() const + { + JSON_ASSERT(anchor.m_object != nullptr); + + switch (anchor.m_object->type()) + { + // use integer array index as key + case value_t::array: + { + if (array_index != array_index_last) + { + int_to_string( array_index_str, array_index ); + array_index_last = array_index; + } + return array_index_str; + } + + // use key from the object + case value_t::object: + return anchor.key(); + + // use an empty key for all primitive types + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return empty_str; + } + } + + /// return value of the iterator + typename IteratorType::reference value() const + { + return anchor.value(); + } +}; + +/// proxy class for the items() function +template class iteration_proxy +{ + private: + /// the container to iterate + typename IteratorType::pointer container = nullptr; + + public: + explicit iteration_proxy() = default; + + /// construct iteration proxy from a container + explicit iteration_proxy(typename IteratorType::reference cont) noexcept + : container(&cont) {} + + iteration_proxy(iteration_proxy const&) = default; + iteration_proxy& operator=(iteration_proxy const&) = default; + iteration_proxy(iteration_proxy&&) noexcept = default; + iteration_proxy& operator=(iteration_proxy&&) noexcept = default; + ~iteration_proxy() = default; + + /// return iterator begin (needed for range-based for) + iteration_proxy_value begin() const noexcept + { + return iteration_proxy_value(container->begin()); + } + + /// return iterator end (needed for range-based for) + iteration_proxy_value end() const noexcept + { + return iteration_proxy_value(container->end()); + } +}; + +// Structured Bindings Support +// For further reference see https://blog.tartanllama.xyz/structured-bindings/ +// And see https://github.com/nlohmann/json/pull/1391 +template = 0> +auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.key()) +{ + return i.key(); +} +// Structured Bindings Support +// For further reference see https://blog.tartanllama.xyz/structured-bindings/ +// And see https://github.com/nlohmann/json/pull/1391 +template = 0> +auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) +{ + return i.value(); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// The Addition to the STD Namespace is required to add +// Structured Bindings Support to the iteration_proxy_value class +// For further reference see https://blog.tartanllama.xyz/structured-bindings/ +// And see https://github.com/nlohmann/json/pull/1391 +namespace std +{ + +#if defined(__clang__) + // Fix: https://github.com/nlohmann/json/issues/1401 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wmismatched-tags" +#endif +template +class tuple_size<::nlohmann::detail::iteration_proxy_value> // NOLINT(cert-dcl58-cpp) + : public std::integral_constant {}; + +template +class tuple_element> // NOLINT(cert-dcl58-cpp) +{ + public: + using type = decltype( + get(std::declval < + ::nlohmann::detail::iteration_proxy_value> ())); +}; +#if defined(__clang__) + #pragma clang diagnostic pop +#endif + +} // namespace std + +#if JSON_HAS_RANGES + template + inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy> = true; +#endif diff --git a/json-develop/include/nlohmann/detail/iterators/iterator_traits.hpp b/json-develop/include/nlohmann/detail/iterators/iterator_traits.hpp new file mode 100644 index 0000000..34a20ee --- /dev/null +++ b/json-develop/include/nlohmann/detail/iterators/iterator_traits.hpp @@ -0,0 +1,61 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // random_access_iterator_tag + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/iterators/json_reverse_iterator.hpp b/json-develop/include/nlohmann/detail/iterators/json_reverse_iterator.hpp new file mode 100644 index 0000000..eb450e9 --- /dev/null +++ b/json-develop/include/nlohmann/detail/iterators/json_reverse_iterator.hpp @@ -0,0 +1,130 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // ptrdiff_t +#include // reverse_iterator +#include // declval + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +////////////////////// +// reverse_iterator // +////////////////////// + +/*! +@brief a template for a reverse iterator class + +@tparam Base the base iterator type to reverse. Valid types are @ref +iterator (to create @ref reverse_iterator) and @ref const_iterator (to +create @ref const_reverse_iterator). + +@requirement The class satisfies the following concept requirements: +- +[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): + The iterator that can be moved can be moved in both directions (i.e. + incremented and decremented). +- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): + It is possible to write to the pointed-to element (only if @a Base is + @ref iterator). + +@since version 1.0.0 +*/ +template +class json_reverse_iterator : public std::reverse_iterator +{ + public: + using difference_type = std::ptrdiff_t; + /// shortcut to the reverse iterator adapter + using base_iterator = std::reverse_iterator; + /// the reference type for the pointed-to element + using reference = typename Base::reference; + + /// create reverse iterator from iterator + explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept + : base_iterator(it) {} + + /// create reverse iterator from base class + explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} + + /// post-increment (it++) + json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp) + { + return static_cast(base_iterator::operator++(1)); + } + + /// pre-increment (++it) + json_reverse_iterator& operator++() + { + return static_cast(base_iterator::operator++()); + } + + /// post-decrement (it--) + json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp) + { + return static_cast(base_iterator::operator--(1)); + } + + /// pre-decrement (--it) + json_reverse_iterator& operator--() + { + return static_cast(base_iterator::operator--()); + } + + /// add to iterator + json_reverse_iterator& operator+=(difference_type i) + { + return static_cast(base_iterator::operator+=(i)); + } + + /// add to iterator + json_reverse_iterator operator+(difference_type i) const + { + return static_cast(base_iterator::operator+(i)); + } + + /// subtract from iterator + json_reverse_iterator operator-(difference_type i) const + { + return static_cast(base_iterator::operator-(i)); + } + + /// return difference + difference_type operator-(const json_reverse_iterator& other) const + { + return base_iterator(*this) - base_iterator(other); + } + + /// access to successor + reference operator[](difference_type n) const + { + return *(this->operator+(n)); + } + + /// return the key of an object iterator + auto key() const -> decltype(std::declval().key()) + { + auto it = --this->base(); + return it.key(); + } + + /// return the value of an iterator + reference value() const + { + auto it = --this->base(); + return it.operator * (); + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/iterators/primitive_iterator.hpp b/json-develop/include/nlohmann/detail/iterators/primitive_iterator.hpp new file mode 100644 index 0000000..0bc3ca8 --- /dev/null +++ b/json-develop/include/nlohmann/detail/iterators/primitive_iterator.hpp @@ -0,0 +1,132 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // ptrdiff_t +#include // numeric_limits + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/* +@brief an iterator for primitive JSON types + +This class models an iterator for primitive JSON types (boolean, number, +string). It's only purpose is to allow the iterator/const_iterator classes +to "iterate" over primitive values. Internally, the iterator is modeled by +a `difference_type` variable. Value begin_value (`0`) models the begin, +end_value (`1`) models past the end. +*/ +class primitive_iterator_t +{ + private: + using difference_type = std::ptrdiff_t; + static constexpr difference_type begin_value = 0; + static constexpr difference_type end_value = begin_value + 1; + + JSON_PRIVATE_UNLESS_TESTED: + /// iterator as signed integer type + difference_type m_it = (std::numeric_limits::min)(); + + public: + constexpr difference_type get_value() const noexcept + { + return m_it; + } + + /// set iterator to a defined beginning + void set_begin() noexcept + { + m_it = begin_value; + } + + /// set iterator to a defined past the end + void set_end() noexcept + { + m_it = end_value; + } + + /// return whether the iterator can be dereferenced + constexpr bool is_begin() const noexcept + { + return m_it == begin_value; + } + + /// return whether the iterator is at end + constexpr bool is_end() const noexcept + { + return m_it == end_value; + } + + friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it == rhs.m_it; + } + + friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it < rhs.m_it; + } + + primitive_iterator_t operator+(difference_type n) noexcept + { + auto result = *this; + result += n; + return result; + } + + friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it - rhs.m_it; + } + + primitive_iterator_t& operator++() noexcept + { + ++m_it; + return *this; + } + + primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + ++m_it; + return result; + } + + primitive_iterator_t& operator--() noexcept + { + --m_it; + return *this; + } + + primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + --m_it; + return result; + } + + primitive_iterator_t& operator+=(difference_type n) noexcept + { + m_it += n; + return *this; + } + + primitive_iterator_t& operator-=(difference_type n) noexcept + { + m_it -= n; + return *this; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/json_custom_base_class.hpp b/json-develop/include/nlohmann/detail/json_custom_base_class.hpp new file mode 100644 index 0000000..ff06653 --- /dev/null +++ b/json-develop/include/nlohmann/detail/json_custom_base_class.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include // conditional, is_same + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief Default base class of the @ref basic_json class. + +So that the correct implementations of the copy / move ctors / assign operators +of @ref basic_json do not require complex case distinctions +(no base class / custom base class used as customization point), +@ref basic_json always has a base class. +By default, this class is used because it is empty and thus has no effect +on the behavior of @ref basic_json. +*/ +struct json_default_base {}; + +template +using json_base_class = typename std::conditional < + std::is_same::value, + json_default_base, + T + >::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/json_pointer.hpp b/json-develop/include/nlohmann/detail/json_pointer.hpp new file mode 100644 index 0000000..eb712ed --- /dev/null +++ b/json-develop/include/nlohmann/detail/json_pointer.hpp @@ -0,0 +1,988 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // all_of +#include // isdigit +#include // errno, ERANGE +#include // strtoull +#ifndef JSON_NO_IO + #include // ostream +#endif // JSON_NO_IO +#include // max +#include // accumulate +#include // string +#include // move +#include // vector + +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document +/// @sa https://json.nlohmann.me/api/json_pointer/ +template +class json_pointer +{ + // allow basic_json to access private members + NLOHMANN_BASIC_JSON_TPL_DECLARATION + friend class basic_json; + + template + friend class json_pointer; + + template + struct string_t_helper + { + using type = T; + }; + + NLOHMANN_BASIC_JSON_TPL_DECLARATION + struct string_t_helper + { + using type = StringType; + }; + + public: + // for backwards compatibility accept BasicJsonType + using string_t = typename string_t_helper::type; + + /// @brief create JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/ + explicit json_pointer(const string_t& s = "") + : reference_tokens(split(s)) + {} + + /// @brief return a string representation of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/to_string/ + string_t to_string() const + { + return std::accumulate(reference_tokens.begin(), reference_tokens.end(), + string_t{}, + [](const string_t& a, const string_t& b) + { + return detail::concat(a, '/', detail::escape(b)); + }); + } + + /// @brief return a string representation of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/ + JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string()) + operator string_t() const + { + return to_string(); + } + +#ifndef JSON_NO_IO + /// @brief write string representation of the JSON pointer to stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ + friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr) + { + o << ptr.to_string(); + return o; + } +#endif + + /// @brief append another JSON pointer at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + json_pointer& operator/=(const json_pointer& ptr) + { + reference_tokens.insert(reference_tokens.end(), + ptr.reference_tokens.begin(), + ptr.reference_tokens.end()); + return *this; + } + + /// @brief append an unescaped reference token at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + json_pointer& operator/=(string_t token) + { + push_back(std::move(token)); + return *this; + } + + /// @brief append an array index at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + json_pointer& operator/=(std::size_t array_idx) + { + return *this /= std::to_string(array_idx); + } + + /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, + const json_pointer& rhs) + { + return json_pointer(lhs) /= rhs; + } + + /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param) + { + return json_pointer(lhs) /= std::move(token); + } + + /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx) + { + return json_pointer(lhs) /= array_idx; + } + + /// @brief returns the parent of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/ + json_pointer parent_pointer() const + { + if (empty()) + { + return *this; + } + + json_pointer res = *this; + res.pop_back(); + return res; + } + + /// @brief remove last reference token + /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/ + void pop_back() + { + if (JSON_HEDLEY_UNLIKELY(empty())) + { + JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); + } + + reference_tokens.pop_back(); + } + + /// @brief return last reference token + /// @sa https://json.nlohmann.me/api/json_pointer/back/ + const string_t& back() const + { + if (JSON_HEDLEY_UNLIKELY(empty())) + { + JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); + } + + return reference_tokens.back(); + } + + /// @brief append an unescaped token at the end of the reference pointer + /// @sa https://json.nlohmann.me/api/json_pointer/push_back/ + void push_back(const string_t& token) + { + reference_tokens.push_back(token); + } + + /// @brief append an unescaped token at the end of the reference pointer + /// @sa https://json.nlohmann.me/api/json_pointer/push_back/ + void push_back(string_t&& token) + { + reference_tokens.push_back(std::move(token)); + } + + /// @brief return whether pointer points to the root document + /// @sa https://json.nlohmann.me/api/json_pointer/empty/ + bool empty() const noexcept + { + return reference_tokens.empty(); + } + + private: + /*! + @param[in] s reference token to be converted into an array index + + @return integer representation of @a s + + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index begins not with a digit + @throw out_of_range.404 if string @a s could not be converted to an integer + @throw out_of_range.410 if an array index exceeds size_type + */ + template + static typename BasicJsonType::size_type array_index(const string_t& s) + { + using size_type = typename BasicJsonType::size_type; + + // error condition (cf. RFC 6901, Sect. 4) + if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) + { + JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr)); + } + + // error condition (cf. RFC 6901, Sect. 4) + if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) + { + JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr)); + } + + const char* p = s.c_str(); + char* p_end = nullptr; + errno = 0; // strtoull doesn't reset errno + const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int) + if (p == p_end // invalid input or empty string + || errno == ERANGE // out of range + || JSON_HEDLEY_UNLIKELY(static_cast(p_end - p) != s.size())) // incomplete read + { + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr)); + } + + // only triggered on special platforms (like 32bit), see also + // https://github.com/nlohmann/json/pull/2203 + if (res >= static_cast((std::numeric_limits::max)())) // NOLINT(runtime/int) + { + JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE + } + + return static_cast(res); + } + + JSON_PRIVATE_UNLESS_TESTED: + json_pointer top() const + { + if (JSON_HEDLEY_UNLIKELY(empty())) + { + JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); + } + + json_pointer result = *this; + result.reference_tokens = {reference_tokens[0]}; + return result; + } + + private: + /*! + @brief create and return a reference to the pointed to value + + @complexity Linear in the number of reference tokens. + + @throw parse_error.109 if array index is not a number + @throw type_error.313 if value cannot be unflattened + */ + template + BasicJsonType& get_and_create(BasicJsonType& j) const + { + auto* result = &j; + + // in case no reference tokens exist, return a reference to the JSON value + // j which will be overwritten by a primitive value + for (const auto& reference_token : reference_tokens) + { + switch (result->type()) + { + case detail::value_t::null: + { + if (reference_token == "0") + { + // start a new array if reference token is 0 + result = &result->operator[](0); + } + else + { + // start a new object otherwise + result = &result->operator[](reference_token); + } + break; + } + + case detail::value_t::object: + { + // create an entry in the object + result = &result->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + // create an entry in the array + result = &result->operator[](array_index(reference_token)); + break; + } + + /* + The following code is only reached if there exists a reference + token _and_ the current value is primitive. In this case, we have + an error situation, because primitive values may only occur as + single value; that is, with an empty list of reference tokens. + */ + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j)); + } + } + + return *result; + } + + /*! + @brief return a reference to the pointed to value + + @note This version does not throw if a value is not present, but tries to + create nested values instead. For instance, calling this function + with pointer `"/this/that"` on a null value is equivalent to calling + `operator[]("this").operator[]("that")` on that value, effectively + changing the null value to an object. + + @param[in] ptr a JSON value + + @return reference to the JSON value pointed to by the JSON pointer + + @complexity Linear in the length of the JSON pointer. + + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + BasicJsonType& get_unchecked(BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + // convert null values to arrays or objects before continuing + if (ptr->is_null()) + { + // check if reference token is a number + const bool nums = + std::all_of(reference_token.begin(), reference_token.end(), + [](const unsigned char x) + { + return std::isdigit(x); + }); + + // change value to array for numbers or "-" or to object otherwise + *ptr = (nums || reference_token == "-") + ? detail::value_t::array + : detail::value_t::object; + } + + switch (ptr->type()) + { + case detail::value_t::object: + { + // use unchecked object access + ptr = &ptr->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + if (reference_token == "-") + { + // explicitly treat "-" as index beyond the end + ptr = &ptr->operator[](ptr->m_data.m_value.array->size()); + } + else + { + // convert array index to number; unchecked access + ptr = &ptr->operator[](array_index(reference_token)); + } + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.402 if the array index '-' is used + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + BasicJsonType& get_checked(BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + // note: at performs range check + ptr = &ptr->at(reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" always fails the range check + JSON_THROW(detail::out_of_range::create(402, detail::concat( + "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), + ") is out of range"), ptr)); + } + + // note: at performs range check + ptr = &ptr->at(array_index(reference_token)); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @brief return a const reference to the pointed to value + + @param[in] ptr a JSON value + + @return const reference to the JSON value pointed to by the JSON + pointer + + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.402 if the array index '-' is used + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + // use unchecked object access + ptr = &ptr->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" cannot be used for const access + JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr)); + } + + // use unchecked array access + ptr = &ptr->operator[](array_index(reference_token)); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.402 if the array index '-' is used + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + const BasicJsonType& get_checked(const BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + // note: at performs range check + ptr = &ptr->at(reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" always fails the range check + JSON_THROW(detail::out_of_range::create(402, detail::concat( + "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), + ") is out of range"), ptr)); + } + + // note: at performs range check + ptr = &ptr->at(array_index(reference_token)); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + */ + template + bool contains(const BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + if (!ptr->contains(reference_token)) + { + // we did not find the key in the object + return false; + } + + ptr = &ptr->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" always fails the range check + return false; + } + if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) + { + // invalid char + return false; + } + if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) + { + if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) + { + // first char should be between '1' and '9' + return false; + } + for (std::size_t i = 1; i < reference_token.size(); i++) + { + if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) + { + // other char should be between '0' and '9' + return false; + } + } + } + + const auto idx = array_index(reference_token); + if (idx >= ptr->size()) + { + // index out of range + return false; + } + + ptr = &ptr->operator[](idx); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + { + // we do not expect primitive values if there is still a + // reference token to process + return false; + } + } + } + + // no reference token left means we found a primitive value + return true; + } + + /*! + @brief split the string input to reference tokens + + @note This function is only called by the json_pointer constructor. + All exceptions below are documented there. + + @throw parse_error.107 if the pointer is not empty or begins with '/' + @throw parse_error.108 if character '~' is not followed by '0' or '1' + */ + static std::vector split(const string_t& reference_string) + { + std::vector result; + + // special case: empty reference string -> no reference tokens + if (reference_string.empty()) + { + return result; + } + + // check if nonempty reference string begins with slash + if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) + { + JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr)); + } + + // extract the reference tokens: + // - slash: position of the last read slash (or end of string) + // - start: position after the previous slash + for ( + // search for the first slash after the first character + std::size_t slash = reference_string.find_first_of('/', 1), + // set the beginning of the first reference token + start = 1; + // we can stop if start == 0 (if slash == string_t::npos) + start != 0; + // set the beginning of the next reference token + // (will eventually be 0 if slash == string_t::npos) + start = (slash == string_t::npos) ? 0 : slash + 1, + // find next slash + slash = reference_string.find_first_of('/', start)) + { + // use the text between the beginning of the reference token + // (start) and the last slash (slash). + auto reference_token = reference_string.substr(start, slash - start); + + // check reference tokens are properly escaped + for (std::size_t pos = reference_token.find_first_of('~'); + pos != string_t::npos; + pos = reference_token.find_first_of('~', pos + 1)) + { + JSON_ASSERT(reference_token[pos] == '~'); + + // ~ must be followed by 0 or 1 + if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || + (reference_token[pos + 1] != '0' && + reference_token[pos + 1] != '1'))) + { + JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr)); + } + } + + // finally, store the reference token + detail::unescape(reference_token); + result.push_back(reference_token); + } + + return result; + } + + private: + /*! + @param[in] reference_string the reference string to the current value + @param[in] value the value to consider + @param[in,out] result the result object to insert values to + + @note Empty objects or arrays are flattened to `null`. + */ + template + static void flatten(const string_t& reference_string, + const BasicJsonType& value, + BasicJsonType& result) + { + switch (value.type()) + { + case detail::value_t::array: + { + if (value.m_data.m_value.array->empty()) + { + // flatten empty array as null + result[reference_string] = nullptr; + } + else + { + // iterate array and use index as reference string + for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i) + { + flatten(detail::concat(reference_string, '/', std::to_string(i)), + value.m_data.m_value.array->operator[](i), result); + } + } + break; + } + + case detail::value_t::object: + { + if (value.m_data.m_value.object->empty()) + { + // flatten empty object as null + result[reference_string] = nullptr; + } + else + { + // iterate object and use keys as reference string + for (const auto& element : *value.m_data.m_value.object) + { + flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result); + } + } + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + { + // add primitive value with its reference string + result[reference_string] = value; + break; + } + } + } + + /*! + @param[in] value flattened JSON + + @return unflattened JSON + + @throw parse_error.109 if array index is not a number + @throw type_error.314 if value is not an object + @throw type_error.315 if object values are not primitive + @throw type_error.313 if value cannot be unflattened + */ + template + static BasicJsonType + unflatten(const BasicJsonType& value) + { + if (JSON_HEDLEY_UNLIKELY(!value.is_object())) + { + JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value)); + } + + BasicJsonType result; + + // iterate the JSON object values + for (const auto& element : *value.m_data.m_value.object) + { + if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) + { + JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second)); + } + + // assign value to reference pointed to by JSON pointer; Note that if + // the JSON pointer is "" (i.e., points to the whole value), function + // get_and_create returns a reference to result itself. An assignment + // will then create a primitive value. + json_pointer(element.first).get_and_create(result) = element.second; + } + + return result; + } + + // can't use conversion operator because of ambiguity + json_pointer convert() const& + { + json_pointer result; + result.reference_tokens = reference_tokens; + return result; + } + + json_pointer convert()&& + { + json_pointer result; + result.reference_tokens = std::move(reference_tokens); + return result; + } + + public: +#if JSON_HAS_THREE_WAY_COMPARISON + /// @brief compares two JSON pointers for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + bool operator==(const json_pointer& rhs) const noexcept + { + return reference_tokens == rhs.reference_tokens; + } + + /// @brief compares JSON pointer and string for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer)) + bool operator==(const string_t& rhs) const + { + return *this == json_pointer(rhs); + } + + /// @brief 3-way compares two JSON pointers + template + std::strong_ordering operator<=>(const json_pointer& rhs) const noexcept // *NOPAD* + { + return reference_tokens <=> rhs.reference_tokens; // *NOPAD* + } +#else + /// @brief compares two JSON pointers for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(const json_pointer& lhs, + const json_pointer& rhs) noexcept; + + /// @brief compares JSON pointer and string for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(const json_pointer& lhs, + const StringType& rhs); + + /// @brief compares string and JSON pointer for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(const StringType& lhs, + const json_pointer& rhs); + + /// @brief compares two JSON pointers for inequality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(const json_pointer& lhs, + const json_pointer& rhs) noexcept; + + /// @brief compares JSON pointer and string for inequality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(const json_pointer& lhs, + const StringType& rhs); + + /// @brief compares string and JSON pointer for inequality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(const StringType& lhs, + const json_pointer& rhs); + + /// @brief compares two JSON pointer for less-than + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator<(const json_pointer& lhs, + const json_pointer& rhs) noexcept; +#endif + + private: + /// the reference tokens + std::vector reference_tokens; +}; + +#if !JSON_HAS_THREE_WAY_COMPARISON +// functions cannot be defined inside class due to ODR violations +template +inline bool operator==(const json_pointer& lhs, + const json_pointer& rhs) noexcept +{ + return lhs.reference_tokens == rhs.reference_tokens; +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer)) +inline bool operator==(const json_pointer& lhs, + const StringType& rhs) +{ + return lhs == json_pointer(rhs); +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer)) +inline bool operator==(const StringType& lhs, + const json_pointer& rhs) +{ + return json_pointer(lhs) == rhs; +} + +template +inline bool operator!=(const json_pointer& lhs, + const json_pointer& rhs) noexcept +{ + return !(lhs == rhs); +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer)) +inline bool operator!=(const json_pointer& lhs, + const StringType& rhs) +{ + return !(lhs == rhs); +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer)) +inline bool operator!=(const StringType& lhs, + const json_pointer& rhs) +{ + return !(lhs == rhs); +} + +template +inline bool operator<(const json_pointer& lhs, + const json_pointer& rhs) noexcept +{ + return lhs.reference_tokens < rhs.reference_tokens; +} +#endif + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/json_ref.hpp b/json-develop/include/nlohmann/detail/json_ref.hpp new file mode 100644 index 0000000..47911fb --- /dev/null +++ b/json-develop/include/nlohmann/detail/json_ref.hpp @@ -0,0 +1,78 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +class json_ref +{ + public: + using value_type = BasicJsonType; + + json_ref(value_type&& value) + : owned_value(std::move(value)) + {} + + json_ref(const value_type& value) + : value_ref(&value) + {} + + json_ref(std::initializer_list init) + : owned_value(init) + {} + + template < + class... Args, + enable_if_t::value, int> = 0 > + json_ref(Args && ... args) + : owned_value(std::forward(args)...) + {} + + // class should be movable only + json_ref(json_ref&&) noexcept = default; + json_ref(const json_ref&) = delete; + json_ref& operator=(const json_ref&) = delete; + json_ref& operator=(json_ref&&) = delete; + ~json_ref() = default; + + value_type moved_or_copied() const + { + if (value_ref == nullptr) + { + return std::move(owned_value); + } + return *value_ref; + } + + value_type const& operator*() const + { + return value_ref ? *value_ref : owned_value; + } + + value_type const* operator->() const + { + return &** this; + } + + private: + mutable value_type owned_value = nullptr; + value_type const* value_ref = nullptr; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/macro_scope.hpp b/json-develop/include/nlohmann/detail/macro_scope.hpp new file mode 100644 index 0000000..2870a4f --- /dev/null +++ b/json-develop/include/nlohmann/detail/macro_scope.hpp @@ -0,0 +1,469 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // declval, pair +#include +#include + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +#include + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used c++ version this is skipped +#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow to access some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType, \ + class CustomBaseClass> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif diff --git a/json-develop/include/nlohmann/detail/macro_unscope.hpp b/json-develop/include/nlohmann/detail/macro_unscope.hpp new file mode 100644 index 0000000..4a871f0 --- /dev/null +++ b/json-develop/include/nlohmann/detail/macro_unscope.hpp @@ -0,0 +1,44 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +// restore clang diagnostic settings +#if defined(__clang__) + #pragma clang diagnostic pop +#endif + +// clean up +#undef JSON_ASSERT +#undef JSON_INTERNAL_CATCH +#undef JSON_THROW +#undef JSON_PRIVATE_UNLESS_TESTED +#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION +#undef NLOHMANN_BASIC_JSON_TPL +#undef JSON_EXPLICIT +#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL +#undef JSON_INLINE_VARIABLE +#undef JSON_NO_UNIQUE_ADDRESS +#undef JSON_DISABLE_ENUM_SERIALIZATION +#undef JSON_USE_GLOBAL_UDLS + +#ifndef JSON_TEST_KEEP_MACROS + #undef JSON_CATCH + #undef JSON_TRY + #undef JSON_HAS_CPP_11 + #undef JSON_HAS_CPP_14 + #undef JSON_HAS_CPP_17 + #undef JSON_HAS_CPP_20 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #undef JSON_HAS_THREE_WAY_COMPARISON + #undef JSON_HAS_RANGES + #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#include diff --git a/json-develop/include/nlohmann/detail/meta/call_std/begin.hpp b/json-develop/include/nlohmann/detail/meta/call_std/begin.hpp new file mode 100644 index 0000000..27d36c6 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/call_std/begin.hpp @@ -0,0 +1,17 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/meta/call_std/end.hpp b/json-develop/include/nlohmann/detail/meta/call_std/end.hpp new file mode 100644 index 0000000..d10bf83 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/call_std/end.hpp @@ -0,0 +1,17 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/meta/cpp_future.hpp b/json-develop/include/nlohmann/detail/meta/cpp_future.hpp new file mode 100644 index 0000000..22f2514 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/cpp_future.hpp @@ -0,0 +1,171 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +inline constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/meta/detected.hpp b/json-develop/include/nlohmann/detail/meta/detected.hpp new file mode 100644 index 0000000..b2f6db9 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/detected.hpp @@ -0,0 +1,70 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/meta/identity_tag.hpp b/json-develop/include/nlohmann/detail/meta/identity_tag.hpp new file mode 100644 index 0000000..71164f2 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/identity_tag.hpp @@ -0,0 +1,21 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// dispatching helper struct +template struct identity_tag {}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/meta/is_sax.hpp b/json-develop/include/nlohmann/detail/meta/is_sax.hpp new file mode 100644 index 0000000..2150089 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/is_sax.hpp @@ -0,0 +1,159 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // size_t +#include // declval +#include // string + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using null_function_t = decltype(std::declval().null()); + +template +using boolean_function_t = + decltype(std::declval().boolean(std::declval())); + +template +using number_integer_function_t = + decltype(std::declval().number_integer(std::declval())); + +template +using number_unsigned_function_t = + decltype(std::declval().number_unsigned(std::declval())); + +template +using number_float_function_t = decltype(std::declval().number_float( + std::declval(), std::declval())); + +template +using string_function_t = + decltype(std::declval().string(std::declval())); + +template +using binary_function_t = + decltype(std::declval().binary(std::declval())); + +template +using start_object_function_t = + decltype(std::declval().start_object(std::declval())); + +template +using key_function_t = + decltype(std::declval().key(std::declval())); + +template +using end_object_function_t = decltype(std::declval().end_object()); + +template +using start_array_function_t = + decltype(std::declval().start_array(std::declval())); + +template +using end_array_function_t = decltype(std::declval().end_array()); + +template +using parse_error_function_t = decltype(std::declval().parse_error( + std::declval(), std::declval(), + std::declval())); + +template +struct is_sax +{ + private: + static_assert(is_basic_json::value, + "BasicJsonType must be of type basic_json<...>"); + + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using exception_t = typename BasicJsonType::exception; + + public: + static constexpr bool value = + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value; +}; + +template +struct is_sax_static_asserts +{ + private: + static_assert(is_basic_json::value, + "BasicJsonType must be of type basic_json<...>"); + + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using exception_t = typename BasicJsonType::exception; + + public: + static_assert(is_detected_exact::value, + "Missing/invalid function: bool null()"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool boolean(bool)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool boolean(bool)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool number_integer(number_integer_t)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool string(string_t&)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool binary(binary_t&)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool start_object(std::size_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool key(string_t&)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool end_object()"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool start_array(std::size_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool end_array()"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool parse_error(std::size_t, const " + "std::string&, const exception&)"); +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/json-develop/include/nlohmann/detail/meta/std_fs.hpp b/json-develop/include/nlohmann/detail/meta/std_fs.hpp new file mode 100644 index 0000000..c096158 --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/std_fs.hpp @@ -0,0 +1,29 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#if JSON_HAS_EXPERIMENTAL_FILESYSTEM +#include +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ +namespace std_fs = std::experimental::filesystem; +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END +#elif JSON_HAS_FILESYSTEM +#include +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ +namespace std_fs = std::filesystem; +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END +#endif diff --git a/json-develop/include/nlohmann/detail/meta/type_traits.hpp b/json-develop/include/nlohmann/detail/meta/type_traits.hpp new file mode 100644 index 0000000..cfc7e5a --- /dev/null +++ b/json-develop/include/nlohmann/detail/meta/type_traits.hpp @@ -0,0 +1,740 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#include // tuple + +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e. those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g. to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g. clang 3.5 or gcc 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to using it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template