wip
[AROS.git] / rom / storage / storage_ids.c
blobce14f5bad822b5c137be2b59f2c7c7335a0d7240
1 /*
2 Copyright 2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
7 #include <aros/debug.h>
9 #include <proto/exec.h>
11 #include <exec/memory.h>
12 #include <aros/symbolsets.h>
14 #include <string.h>
16 #include "storage_intern.h"
18 //#include LC_LIBDEFS_FILE
20 int FindFirstDigit(char *inString)
22 int inStr_len = strlen(inString);
23 int i = 0;
25 for (i = 0; i < inStr_len; i++)
27 if ((inString[i] >= 0x30) && (inString[i] <= 0x39))
28 return i;
30 return -1;
33 struct Storage_IDFamily *FindIDFamily(char *ID, struct StorageBase_intern *StorageBase)
35 struct Storage_IDFamily *_IDFamiily = NULL;
36 int firstDigit;
38 firstDigit = FindFirstDigit(ID);
40 ForeachNode(&StorageBase->libb_NameSpaceFamilies, _IDFamiily)
42 if (firstDigit == -1)
44 if ((strcmp(_IDFamiily->SIDF_Node.ln_Name, ID)) == 0)
45 return _IDFamiily;
47 else
49 if ((strlen(_IDFamiily->SIDF_Node.ln_Name) == firstDigit) && ((strncmp(_IDFamiily->SIDF_Node.ln_Name, ID, firstDigit)) == 0))
50 return _IDFamiily;
53 return NULL;
56 /*****************************************************************************
58 NAME */
60 AROS_LH1(struct Storage_IDNode *, AllocateID,
62 /* SYNOPSIS */
63 AROS_LHA(char *, ID, A0),
65 /* LOCATION */
66 APTR *, StorageBase, 10, Storage)
68 /* FUNCTION
69 Allocate a unit/volume ID.
71 INPUTS
72 ID - base ID to allocate. If no unit is specified (e.g. ID = "CD"), a new
73 ID for that family will be allocated (e.g "CD0", "CD1", etc). If an ID unit _is_
74 specified, and it is allready allocated - a new ID will be created (e.g. "CD0_1")
76 RESULT
78 NOTES
80 EXAMPLE
82 BUGS
84 SEE ALSO
86 INTERNALS
88 ******************************************************************************/
90 AROS_LIBFUNC_INIT
92 struct Storage_IDFamily *_IDFamiily = NULL;
93 struct Storage_IDNode *_IDNode = NULL;
94 int firstDigit;
95 ULONG freeValue = 0;
97 D(bug("[StorageRes] %s('%s')\n", __PRETTY_FUNCTION__, ID));
99 if ((_IDFamiily = FindIDFamily(ID, (struct StorageBase_intern *)StorageBase)) == NULL)
101 if ((_IDFamiily = AllocVec(sizeof(struct Storage_IDFamily), MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
103 int baseNameLength = strlen(ID);
105 NEWLIST(&_IDFamiily->SIDF_IDs);
106 _IDFamiily->SIDF_Node.ln_Name = AllocVec(baseNameLength + 1, MEMF_CLEAR|MEMF_PUBLIC);
107 CopyMem(ID, _IDFamiily->SIDF_Node.ln_Name, baseNameLength);
108 AddTail(&((struct StorageBase_intern *)StorageBase)->libb_NameSpaceFamilies, &_IDFamiily->SDNF_Node);
109 D(bug("[StorageRes] AllocateID: New FamilyNode @ 0x%p for '%s'\n", _IDFamiily, _IDFamiily->SIDF_Node.ln_Name));
111 else
113 D(bug("[StorageRes] AllocateID: ERROR - No Mem to allocate FamilyNode\n"));
114 return NULL;
118 D(bug("[StorageRes] AllocateID: using FamilyNode @ 0x%p (family '%s')\n", _IDFamiily, _IDFamiily->SIDF_Node.ln_Name));
120 #warning "TODO: We should use locking when manipulating the name list !"
122 ForeachNode(&_IDFamiily->SIDF_IDs, _IDNode)
124 ULONG nodeValue = 0;
125 int i;
127 firstDigit = FindFirstDigit(_IDNode->SIDN_Node.ln_Name);
129 for (i = 0; i < (strlen(_IDNode->SIDN_Node.ln_Name) - firstDigit); i++)
131 nodeValue = nodeValue * 10;
132 nodeValue = nodeValue + (_IDNode->SIDN_Node.ln_Name[firstDigit + i] - 0x30);
134 //find the index of the value in the name
135 //convert it to a real value
136 if (nodeValue >= freeValue)
138 freeValue = nodeValue +1;
141 D(bug("[StorageRes] AllocateID: Free Device ID : %d\n", freeValue));
143 _IDNode = NULL;
145 if ((_IDNode = AllocVec(sizeof(struct Storage_IDNode), MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
147 int baseNameLength = strlen(ID);
148 int freeValue_len = 1;
149 if (freeValue >= 10) freeValue_len ++;
150 if (freeValue >= 100) freeValue_len ++;
152 _IDNode->SIDN_Node.ln_Name = AllocVec(baseNameLength + freeValue_len + 2, MEMF_CLEAR|MEMF_PUBLIC);
154 D(bug("[StorageRes] AllocateID: Name Node Allocated @ 0x%p, Name Storage @ 0x%p [%d bytes]\n", _IDNode, _IDNode->SIDN_Node.ln_Name, (baseNameLength + freeValue_len + 2)));
156 CopyMem(_IDFamiily->SIDF_Node.ln_Name, _IDNode->SIDN_Node.ln_Name, baseNameLength);
157 int startnum = freeValue;
158 int count = 0;
159 if (freeValue >= 100)
161 _IDNode->SIDN_Node.ln_Name[baseNameLength + count] = (char)(0x30 + (freeValue / 100));
162 freeValue = freeValue - ((freeValue / 100) * 100);
163 count ++;
165 if (freeValue >= 10)
167 _IDNode->SIDN_Node.ln_Name[baseNameLength + count] = (char)(0x30 + (freeValue / 10));
168 freeValue = freeValue - ((freeValue / 10) * 10);
169 count ++;
171 _IDNode->SIDN_Node.ln_Name[baseNameLength + count] = (char)(0x30 + freeValue);
172 freeValue = startnum;
173 count ++;
174 _IDNode->SIDN_Node.ln_Name[baseNameLength + count] = 0x00;
176 Enqueue(&_IDFamiily->SIDF_IDs, &_IDNode->SDNN_Node);
177 D(bug("[StorageRes] AllocateID: Node '%s' Done\n", _IDNode->SIDN_Node.ln_Name));
179 return _IDNode;
182 return NULL;
184 AROS_LIBFUNC_EXIT
185 } /* AllocateID */
188 AROS_LH1(BOOL, FreeID,
189 AROS_LHA(struct Storage_IDNode *, _IDNode, A0),
190 APTR *, StorageBase, 11, Storage)
192 /* FUNCTION
193 Free a device/volume ID.
195 INPUTS
196 ID Node.
198 RESULT
200 NOTES
202 EXAMPLE
204 BUGS
206 SEE ALSO
208 INTERNALS
210 ******************************************************************************/
212 AROS_LIBFUNC_INIT
214 struct Storage_IDFamily *_IDFamiily = NULL;
216 D(bug("[StorageRes] %s('%s')\n", __PRETTY_FUNCTION__, _IDNode->SIDN_Node.ln_Name));
218 return TRUE;
220 AROS_LIBFUNC_EXIT
221 } /* FreeID */