home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / dn511.exe / DSOBJECT.CPP < prev    next >
Text File  |  1995-02-16  |  12KB  |  372 lines

  1. /*
  2. **    Copyright ⌐ 1994 Novell, Inc.  All rights reserved.
  3. **
  4. **    Permission is granted to the recipient of this work ("you") to use,
  5. **    reproduce and distribute Novell's original publication of the work free
  6. **    of charge provided that you reproduce the work in its entirety and
  7. **    include all Novell copyright notices as they originally appear.
  8. **
  9. **    Novell grants you permission to modify and distribute copies of this
  10. **    work including any portion of this work (a "modified work") provided
  11. **    that you include prominent notification of such modification along with
  12. **    the date of modification on a modified work; distribute or publish a
  13. **    modified work to third parties under the same conditions and granting
  14. **    the same rights as are extended to you by Novell under this under
  15. **    permission notice; and provided that you include a copy of Novell's
  16. **    original publication of the work along with any copy of a modified
  17. **    work.
  18. **
  19. **    NOVELL MAKES NO WARRANTY, REPRESENTATION OR PROMISE THAT THIS WORK OR A
  20. **    MODIFIED WORK WILL SATISFY YOUR REQUIREMENTS OR THAT THIS WORK OR A
  21. **    MODIFIED WORK IS WITHOUT DEFECT OR ERROR.  NOVELL DISCLAIMS AND
  22. **    EXCLUDES ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY, TITLE OR
  23. **    FITNESS FOR A PARTICULAR PURPOSE.
  24. **
  25. **    IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NOVELL OR ANY OTHER
  26. **    PARTY BE LIABLE FOR DAMAGES INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
  27. **    CONSEQUENTIAL, INDIRECT OR PUNATIVE DAMAGES ARISING OUT OF THE USE OF
  28. **    OR INABLITITY TO USE THE WORK OR A MODIFIED WORK.
  29. **
  30. **    DSOBJECT.CPP - October 1994
  31. **
  32. **    Definition of the DSObject class.
  33. **
  34. **    Author: John Buckle, Asia Pacific Support Centre, Novell Australia
  35. **    ==================================================================
  36. **    9 Jan 1995           First release              John Buckle
  37. */
  38.  
  39. # include "dsdefs.h"
  40. # include "dsobject.h"
  41. # include "dsvmulti.h"
  42.  
  43. # include <string.h>
  44.  
  45. /*
  46. ** DSObject::WriteBufferModified    Used to indicate if an object has been
  47. **                    modified, and hence whether the NDS
  48. **                    needs to be updated.
  49. */
  50.  
  51. int DSObject::WriteBufferModified = 0 ;
  52.  
  53. /*
  54. ** NWDSCCODE DSObject::ReadObject(NWPSTR rdn, DSBuffer * buffer)
  55. **
  56. **    Initialise the DSObject by reading the required attributes off
  57. **    the NDS. The attributes to read are listed the object's attribute
  58. **    and value count arrays, which is accessed using the virtual functions
  59. **    AttributeNames() and AttributeCount().
  60. */
  61.  
  62. NWDSCCODE DSObject::ReadObject(NWPSTR rdn, DSBuffer * buffer)
  63. {
  64. DSReadObject    dsReadObject(this) ;
  65. NWPSTR *    attrNames = AttributeNames() ;
  66. WORD *        attrCount = AttributeCount() ;
  67.  
  68.     buffer->InitBuf(DSV_READ) ;
  69.  
  70.     for (int index = 0 ; attrNames[index] ; index++)
  71.         if (attrCount[index])
  72.             buffer->PutAttrName(attrNames[index]) ;
  73.  
  74.     return buffer->Read(rdn,1,0,& dsReadObject) ;
  75. } ;
  76.  
  77. /*
  78. ** NWDSCCODE DSObject::WriteObject(
  79. **            NWPSTR        rdn,
  80. **            DSBuffer *    buffer,
  81. **            DSObject *    oldObject = 0)
  82. **
  83. **    Create or modify the NDS copy of the object. If oldObject is null then
  84. **    a new object is created. Otherwise the object is compared with the
  85. **    oldObject and modifications are recorded in the DSBuffer object.
  86. */
  87.  
  88. NWDSCCODE DSObject::WriteObject(NWPSTR rdn, DSBuffer * buffer, DSObject * oldObject)
  89. {
  90.     if (oldObject)
  91.         buffer->InitBuf(DSV_MODIFY_ENTRY) ;
  92.     else {
  93.         buffer->InitBuf(DSV_ADD_ENTRY) ;
  94.         buffer->PutAttrName("Object Class",SYN_CLASS_NAME,ClassName()) ;
  95.         }
  96.  
  97.     WriteBufferModified = 0 ;
  98.     NWDSCCODE status    = ForAll(WriteAll,buffer,oldObject) ;
  99.     if (status || WriteBufferModified == 0) return status ;
  100.  
  101.     return (oldObject)
  102.         ? buffer->ModifyObject(rdn)
  103.         : buffer->AddObject(rdn) ;
  104. } ;
  105.  
  106. /*
  107. ** NWDSCCODE DSObject::CompareObject(DSObject * oldObject)
  108. **
  109. **    Returns 0 if oldObject is the same as this object.
  110. */
  111.  
  112. NWDSCCODE DSObject::CompareObject(DSObject * oldObject)
  113. {
  114.     WriteBufferModified = 0 ;
  115.  
  116.     return ForAll(WriteAll,0,oldObject) || WriteBufferModified ;
  117. } ;
  118.  
  119. /*
  120. ** NWDSCCODE DSObject::WriteNewValue(
  121. **            DSBuffer *    buffer,
  122. **            NWPSTR        attribute,
  123. **            DSValue *    newValue)
  124. **
  125. **    Write a new NDS value to the buffer. This function is executed when
  126. **    a new NDS object is created. If buffer is null then two DSObjects are
  127. **    being compared, hence return 1 to indicate that they are different.
  128. */
  129.  
  130. NWDSCCODE DSObject::WriteNewValue(DSBuffer * buffer, NWPSTR attribute, DSValue * newValue)
  131. {
  132.     WriteBufferModified = 1 ;
  133.  
  134.     if (buffer == 0) return 1 ;
  135.  
  136.     if (newValue->Syntax == 0) return 0 ;
  137.  
  138.     if (newValue->type() == DSCPP_MULTI_VALUE){
  139.         DSVMultiValue & newMulti = * (DSVMultiValue *) newValue ;
  140.         buffer->PutAttrName(attribute) ;
  141.         for (DSValueIterator iter(newMulti.List) ; iter() ; iter.next()){
  142.             buffer->PutAttrValue(iter()->Syntax,iter()->data()) ;
  143.             }
  144.         }
  145.     else {
  146.         buffer->PutAttrName(attribute,newValue->Syntax,newValue->data()) ;
  147.         }
  148.  
  149.     return buffer->status() ;
  150. }
  151.  
  152. /*
  153. ** NWDSCCODE DSObject::WriteSingleValue(
  154. **            DSBuffer *    buffer,
  155. **            NWPSTR        attribute,
  156. **            DSValue *    newValue,
  157. **            DSValue *    oldValue)
  158. **
  159. **    Compare the values and delete the old value and/or add the new value.
  160. **    This function is executed when an NDS object is modified. If buffer is
  161. **    null then two DSObjects are being compared, hence return the state of
  162. **    WriteBufferModified.
  163. */
  164.  
  165. NWDSCCODE DSObject::WriteSingleValue(
  166.             DSBuffer *    buffer,
  167.             NWPSTR        attribute,
  168.             DSValue *    newValue,
  169.             DSValue *    oldValue)
  170. {
  171.     if (newValue->Syntax == oldValue->Syntax && * newValue == * oldValue)
  172.         return 0 ;
  173.  
  174.     if (oldValue->Syntax > 0){
  175.         WriteBufferModified = 1 ;
  176.         if (buffer) buffer->DelAttrValue(attribute,oldValue->Syntax,oldValue->data()) ;
  177.         }
  178.     if (newValue->Syntax > 0){
  179.         WriteBufferModified = 1 ;
  180.         if (buffer) buffer->AddAttrValue(attribute,newValue->Syntax,newValue->data()) ;
  181.         }
  182.     return (buffer) ? buffer->status() : WriteBufferModified ;
  183. }
  184.  
  185. /*
  186. ** NWDSCCODE DSObject::WriteMultiValue(
  187. **            DSBuffer *    buffer,
  188. **            NWPSTR        attribute,
  189. **            DSValue *    newValue,
  190. **            DSValue *    oldValue)
  191. **
  192. **    Compare the two multivalue values and delete the old values and/or
  193. **    add the new values. This function is called when an NDS object is
  194. **    modified. If buffer is null then two DSObjects are being compared,
  195. **    hence return the state of WriteBufferModified.
  196. */
  197.  
  198. NWDSCCODE DSObject::WriteMultiValue(
  199.             DSBuffer *    buffer,
  200.             NWPSTR        attribute,
  201.             DSValue *    newValue,
  202.             DSValue *    oldValue)
  203. {
  204. DSVMultiValue & newMulti = * (DSVMultiValue *) newValue ;
  205. DSVMultiValue & oldMulti = * (DSVMultiValue *) oldValue ;
  206.  
  207.     for (DSValueIterator oldIter(oldMulti.List) ; oldIter() ; oldIter.next()){
  208.         DSValue * value = oldIter() ;
  209.         if ((newMulti == * value) == 0){
  210.             WriteBufferModified = 1 ;
  211.             if (buffer) buffer->DelAttrValue(attribute,value->Syntax,value->data()) ;
  212.             }
  213.         }
  214.  
  215.     for (DSValueIterator newIter(newMulti.List) ; newIter() ; newIter.next()){
  216.         DSValue * value = newIter() ;
  217.         if ((oldMulti == * value) == 0){
  218.             WriteBufferModified = 1 ;
  219.             if (buffer) buffer->AddAttrValue(attribute,value->Syntax,value->data()) ;
  220.             }
  221.         }
  222.  
  223.     return (buffer) ? buffer->status() : WriteBufferModified ;
  224. }
  225.  
  226. /*
  227. ** NWDSCCODE DSObject::ForAll(DSForAllFunc func, void * data1, void * data2)
  228. **
  229. **    Execute func() on all attribute values passing the two data parameters.
  230. **    If the function returns a non zero value then the iteration is aborted.
  231. */
  232.  
  233. NWDSCCODE DSObject::ForAll(DSForAllFunc func, void * data1, void * data2)
  234. {
  235. NWPSTR *    attrNames = AttributeNames() ;
  236. WORD   *    attrCount = AttributeCount() ;
  237. DSForAllData    data ;
  238. NWDSCCODE    ccode = 0 ;
  239.  
  240.     data.object = this ;
  241.     data.data1  = data1 ;
  242.     data.data2  = data2 ;
  243.  
  244.     for (data.attrIndex = 0 ; attrNames[data.attrIndex] ; data.attrIndex++){
  245.         for (data.valueIndex = 0 ; data.valueIndex < attrCount[data.attrIndex] ; data.valueIndex++){
  246.             DSValue * value = FindAttribute(data.attrIndex,data.valueIndex) ;
  247.             if (value == 0) break ;
  248.             if ((ccode = func(value,& data)) != 0) return ccode ;
  249.             }
  250.         }
  251.     return 0 ;
  252. }
  253.  
  254. /*
  255. ** NWDSCCODE DSObject::ReleaseAll(DSValue * value, DSForAllData * data)
  256. **
  257. **    Deallocate memory used by the attribute value. This function is a
  258. **    private static member of DSObject. It is executed from a ForAll()
  259. **    iteration started by calling Release().
  260. */
  261.  
  262. NWDSCCODE DSObject::ReleaseAll(DSValue * value, DSForAllData *)
  263. {
  264.     return value->release() ;
  265. }
  266.  
  267. /*
  268. ** NWDSCCODE DSObject::WriteAll(DSValue * newValue, DSForAllData * data)
  269. **
  270. **    Determine if the attribute value has been modified and write the
  271. **    value to the DSBuffer if it has. This is a private static member of
  272. **    DSObject. It is executed from a ForAll() iteration started by
  273. **    calling WriteObject().
  274. */
  275.  
  276. NWDSCCODE DSObject::WriteAll(DSValue * newValue, DSForAllData * data)
  277. {
  278. DSBuffer * buffer    = (DSBuffer *) data->data1 ;
  279. DSObject * oldObject = (DSObject *) data->data2 ;
  280. NWPSTR       attribute = data->object->AttributeNames()[data->attrIndex] ;
  281.  
  282.     if (oldObject == 0)
  283.         return WriteNewValue(buffer,attribute,newValue) ;
  284.  
  285.     DSValue * oldValue = oldObject->FindAttribute(data->attrIndex,data->valueIndex) ;
  286.  
  287.     if (oldValue == 0)
  288.         return DSCPP_MEMORY_ERROR ;
  289.  
  290.     if (oldValue->type() != newValue->type())
  291.         return DSCPP_WRONG_TYPE ;
  292.  
  293.     if (oldValue->Syntax == 0 && newValue->Syntax == 0)
  294.         return 0 ;
  295.  
  296.     if (oldValue->Syntax == 0 && data->valueIndex == 0){
  297.         WriteBufferModified = 1 ;
  298.         if (buffer) buffer->PutChange(DS_ADD_ATTRIBUTE,attribute) ;
  299.         }
  300.     if (newValue->type() != DSCPP_MULTI_VALUE)
  301.         return WriteSingleValue(buffer,attribute,newValue,oldValue) ;
  302.  
  303.     return WriteMultiValue(buffer,attribute,newValue,oldValue) ;
  304. }
  305.  
  306. /*
  307. ** NWDSCCODE DSObject::DisplayAll(DSValue * value, DSForAllData * data)
  308. **
  309. **    Print a text version of each attribute value. This function is a
  310. **    private static member of DSObject. It is executed from a ForAll()
  311. **    iteration started by calling OStream().
  312. */
  313.  
  314. #ifdef DSCPP_IOSTREAM
  315. NWDSCCODE DSObject::DisplayAll(DSValue * value, DSForAllData * data)
  316. {
  317. ostream & s = * (ostream *) data->data1 ;
  318.  
  319.     if (data->valueIndex == 0)
  320.         s << data->object->AttributeNames()[data->attrIndex] << "::\n" ;
  321.  
  322.     if (value->type() == DSCPP_MULTI_VALUE){
  323.         DSVMultiValue * multi = (DSVMultiValue *) value ;
  324.         for (DSValueIterator iter(multi->List) ; iter() ; iter.next())
  325.             s << * iter() << endl ;
  326.         }
  327.     else {
  328.         if (value->Syntax) s << * value << endl ;
  329.         }
  330.  
  331.     return 0 ;
  332. }
  333. #endif DSCPP_IOSTREAM
  334.  
  335. /*
  336. ** NWDSCCODE DSReadObject::SetAttrName(NWPSTR attrName, NWSYNTAX_ID)
  337. **
  338. **    Determine the index of the attribute returned from the NWDSRead()
  339. **    operation. Given that this is a new attribute the ValueIndex is set
  340. **    to zero.
  341. */
  342.  
  343. NWDSCCODE DSReadObject::SetAttrName(NWPSTR attrName, NWSYNTAX_ID)
  344. {
  345. NWPSTR*    attributes = Object->AttributeNames() ;
  346.     ValueIndex = 0 ;
  347.  
  348.     for (AttrIndex = 0 ; attributes[AttrIndex] ; AttrIndex++)
  349.         if (stricmp(attributes[AttrIndex],attrName) == 0) break ;
  350.  
  351.     return 0 ;
  352. }
  353.  
  354. /*
  355. ** NWDSCCODE DSReadObject::SetAttrValue(NWSYNTAX_ID syntaxID, void * data)
  356. **
  357. **    Find the DSValue object that should be used to store the data from
  358. **    a NWDSRead() operation. A pointer to the value object is obtained
  359. **    by calling DSObject::FindAttribute(). If this returns a null pointer
  360. **    then the data is discarded.
  361. */
  362.  
  363. NWDSCCODE DSReadObject::SetAttrValue(NWSYNTAX_ID syntaxID, void * data)
  364. {
  365. DSValue * value = Object->FindAttribute(AttrIndex,ValueIndex++) ;
  366.  
  367.     if (value) value->assign(syntaxID,data) ;
  368.  
  369.     return 0 ;
  370. }
  371.  
  372.