Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to design (and do I want) an API?

How to design (and do I want) an API?

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsdesignjsonhelptutorial
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    piul
    wrote on last edited by
    #1

    Hi, I'm working on a small libarary that will parse and modify a certain type of configuration file. As suggested by wise people (I think) I'd like to hide away the implementation and offer the user a set of functions to use the library. I have questions mainly philosophical or concerning style. I'll put here my idea and it'd be very nice to get your opinions on it.

    #ifndef CONFIGFILEAPI_H_INCLUDED
    #define CONFIGFILEAPI_H_INCLUDED

    #include
    #include

    namespace cfgFileLib
    {
    //open and parse a file
    // Returns:
    // empty string "" if succesful
    // error description if not
    std::string openConfigFile (const std::string & fileName);

    //check if a symbol is defined
    bool isDefined (const std::string & symbol);

    //how many values are assigned this symbol
    int howMany (const std::string & symbol);

    //get first (or only) value assigned to the given symbol
    bool getBool (const std::string & symbol);
    int getInt (const std::string & symbol);
    double getDouble (const std::string & symbol);
    std::string getString (const std::string & symbol);

    //get all the values assgined to the given symbol
    std::vector getAllBool (const std::string & symbol);
    std::vector getAllInt (const std::string & symbol);
    std::vector getAllDouble (const std::string & symbol);
    std::vector getAllString (const std::string & symbol);
    }
    #endif

    - Does this design make sense in general? - Do I put it all whithin a namespace?

    E C 2 Replies Last reply
    0
    • P piul

      Hi, I'm working on a small libarary that will parse and modify a certain type of configuration file. As suggested by wise people (I think) I'd like to hide away the implementation and offer the user a set of functions to use the library. I have questions mainly philosophical or concerning style. I'll put here my idea and it'd be very nice to get your opinions on it.

      #ifndef CONFIGFILEAPI_H_INCLUDED
      #define CONFIGFILEAPI_H_INCLUDED

      #include
      #include

      namespace cfgFileLib
      {
      //open and parse a file
      // Returns:
      // empty string "" if succesful
      // error description if not
      std::string openConfigFile (const std::string & fileName);

      //check if a symbol is defined
      bool isDefined (const std::string & symbol);

      //how many values are assigned this symbol
      int howMany (const std::string & symbol);

      //get first (or only) value assigned to the given symbol
      bool getBool (const std::string & symbol);
      int getInt (const std::string & symbol);
      double getDouble (const std::string & symbol);
      std::string getString (const std::string & symbol);

      //get all the values assgined to the given symbol
      std::vector getAllBool (const std::string & symbol);
      std::vector getAllInt (const std::string & symbol);
      std::vector getAllDouble (const std::string & symbol);
      std::vector getAllString (const std::string & symbol);
      }
      #endif

      - Does this design make sense in general? - Do I put it all whithin a namespace?

      E Offline
      E Offline
      Espen Harlinn
      wrote on last edited by
      #2

      Have a look at Boost.PropertyTree[^] I think it's a well designed library - it's worth taking a look at it's implementation. >> Does this design make sense in general? Normally you would create a class that is able to hold more than one configuration entry, and then something representing the various kinds of entries. >> Do I put it all whithin a namespace? That's usually a good idea :-) Best regards Espen Harlinn

      Espen Harlinn Chief Architect - Powel AS Projects promoting programming in "natural language" are intrinsically doomed to fail. Edsger W.Dijkstra

      P 1 Reply Last reply
      0
      • E Espen Harlinn

        Have a look at Boost.PropertyTree[^] I think it's a well designed library - it's worth taking a look at it's implementation. >> Does this design make sense in general? Normally you would create a class that is able to hold more than one configuration entry, and then something representing the various kinds of entries. >> Do I put it all whithin a namespace? That's usually a good idea :-) Best regards Espen Harlinn

        Espen Harlinn Chief Architect - Powel AS Projects promoting programming in "natural language" are intrinsically doomed to fail. Edsger W.Dijkstra

        P Offline
        P Offline
        piul
        wrote on last edited by
        #3

        Thanks Espen. I'll take a look at Boost.PropertyTree I didn't get what you meant by

        Espen Harlinn wrote:

        Normally you would create a class that is able to hold more than one configuration entry, and then something representing the various kinds of entries.

        E 1 Reply Last reply
        0
        • P piul

          Thanks Espen. I'll take a look at Boost.PropertyTree I didn't get what you meant by

          Espen Harlinn wrote:

          Normally you would create a class that is able to hold more than one configuration entry, and then something representing the various kinds of entries.

          E Offline
          E Offline
          Espen Harlinn
          wrote on last edited by
          #4

          Something structured somewhat like this:

          class ConfigEntry
          {

          };

          class ConfigNode : public ConfigEntry
          {
          typedef std::map > EntryMap;
          EntryMap entryMap_;

          };

          class ConfigValue : public ConfigEntry
          {
          };

          class StringConfigValue : public ConfigValue
          {
          std::string value_;
          };

          class IntConfigValue : public ConfigValue
          {
          int value_;
          };

          class ConfigFile : public ConfigNode
          {
          };

          This way the EntryMap can hold std::string, int and nested ConfigNode objects.

          Espen Harlinn Chief Architect - Powel AS Projects promoting programming in "natural language" are intrinsically doomed to fail. Edsger W.Dijkstra

          1 Reply Last reply
          0
          • P piul

            Hi, I'm working on a small libarary that will parse and modify a certain type of configuration file. As suggested by wise people (I think) I'd like to hide away the implementation and offer the user a set of functions to use the library. I have questions mainly philosophical or concerning style. I'll put here my idea and it'd be very nice to get your opinions on it.

            #ifndef CONFIGFILEAPI_H_INCLUDED
            #define CONFIGFILEAPI_H_INCLUDED

            #include
            #include

            namespace cfgFileLib
            {
            //open and parse a file
            // Returns:
            // empty string "" if succesful
            // error description if not
            std::string openConfigFile (const std::string & fileName);

            //check if a symbol is defined
            bool isDefined (const std::string & symbol);

            //how many values are assigned this symbol
            int howMany (const std::string & symbol);

            //get first (or only) value assigned to the given symbol
            bool getBool (const std::string & symbol);
            int getInt (const std::string & symbol);
            double getDouble (const std::string & symbol);
            std::string getString (const std::string & symbol);

            //get all the values assgined to the given symbol
            std::vector getAllBool (const std::string & symbol);
            std::vector getAllInt (const std::string & symbol);
            std::vector getAllDouble (const std::string & symbol);
            std::vector getAllString (const std::string & symbol);
            }
            #endif

            - Does this design make sense in general? - Do I put it all whithin a namespace?

            C Offline
            C Offline
            Cristian Amarie
            wrote on last edited by
            #5

            If you're using this in C++ only, seems ok (let alone the preferences). However, I'd do this: - no namespace exports; be wary of linker decorations - export just the needed functions, not all (i.e. the "public" interface) - separate helpers from actors (i.e openConfigFile, isDefined vs getBool, getInt) - do not return std::string or others from functions; rather, return just simple testable values (int, bool) and change to bool openConfigFile(const std::string& filename, std::string& result); (or std::string* result) - if you'll get this used in other places, favor a C-like interface and do the plumbing code, such as BOOL WINAPI OpenConfigFileA(LPCSTR fileName, LPSTR* result); or use VARIANTs is needed in VBS. - or favor the COM-like exports with just structs with virtual pure functions and DllGetClassObject-like creators. There are many things to consider. I'm using sometimes even paper and pen to weight all these.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups