1/*
2 * Copyright 2001-2006 Ingo Weinhold, bonefish@cs.tu-berlin.de
3 * Copyright 2013 Haiku Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 *		John Scipione, jscipione@gmail.com
8 *		Ingo Weinhold, bonefish@users.sf.net
9 *
10 * Corresponds to:
11 *		headers/os/storage/Resources.h	hrev47402
12 *		src/kits/storage/Resources.cpp	hrev47402
13 */
14
15
16/*!
17	\file Resources.h
18	\ingroup storage
19	\ingroup libbe
20	\brief Provides the BResources class.
21*/
22
23
24/*!
25	\class BResources
26	\ingroup storage
27	\ingroup libbe
28	\brief Provides an interface for accessing and manipulating file
29	       resources.
30
31	BResources delegates most of the work to ResourcesContainer and
32	ResourceFile. The former manages a collections of ResourceItem objects's
33	(the actual resources) whereas the latter provides the file I/O
34	functionality.
35
36	An InitCheck() method is not needed, since a BResources object will
37	never be invalid. It always serves as a resources container, even if
38	it is not associated with a file. It is always possible to WriteTo()
39	the resources BResources contains to a file (a valid one of course).
40
41	\since BeOS R3
42*/
43
44
45/*!
46	\fn BResources::BResources()
47	\brief Creates an uninitialized BResources object.
48
49	\see SetTo()
50
51	\since BeOS R3
52*/
53
54
55/*!
56	\fn BResources::BResources(const BFile* file, bool clobber)
57	\brief Creates a BResources object that represents the resources of the
58	       supplied \a file.
59
60	If the \a clobber argument is \c true, the data of the file are erased
61	and it is turned into an empty resource file. Otherwise \a file
62	must refer either to a resource file or to an executable (ELF or PEF
63	binary). If the file has been opened \c B_READ_ONLY, only read access
64	to its resources is possible.
65
66	The BResources object makes a copy of \a file, that is the caller remains
67	owner of the BFile object.
68
69	\param file The file to create a BResource object from.
70	\param clobber If \c true, the data of the file are erased.
71
72	\since BeOS R3
73*/
74
75
76/*!
77	\fn BResources::BResources(const char* path, bool clobber)
78	\brief Creates a BResources object that represents the resources of the
79	       file referenced by the supplied \a path.
80
81	If the \a clobber argument is \c true, the data of the file are erased
82	and it is turned into an empty resource file. Otherwise \a path
83	must refer either to a resource file or to an executable (ELF or PEF
84	binary).
85
86	\param path A path referring to the file to create a BResource object
87	       from.
88	\param clobber If \c true, the data of the file are erased.
89
90	\since Haiku R1
91*/
92
93
94/*!
95	\fn BResources::BResources(const entry_ref* ref, bool clobber)
96	\brief Creates a BResources object that represents the resources of the
97	       file referenced by the supplied \a ref.
98
99	If the \a clobber argument is \c true, the data of the file are erased
100	and it is turned into an empty resource file. Otherwise \a ref
101	must refer either to a resource file or to an executable (ELF or PEF
102	binary).
103
104	\param ref An entry_ref referring to the file to create a BResource object
105	       from.
106	\param clobber If \c true, the data of the file are erased.
107
108	\since Haiku R1
109*/
110
111
112/*!
113	\fn BResources::~BResources()
114	\brief Destroys the BResources object and frees any associated resources.
115
116	Sync() is first called to make sure that the changes are written back to
117	the file.
118
119	\since BeOS R3
120*/
121
122
123/*!
124	\name SetTo
125
126	What happens, if \a clobber is \c true, depends on the type of the file.
127	If the file is capable of containing resources, that is, is a resource
128	file or an executable (ELF or PEF), its resources are removed. Otherwise
129	the file's data are erased and it is turned into an empty resource file.
130	If \a clobber is \c false, \a file must refer to a file that is capable
131	of containing resources.
132
133	If the file has been opened \c B_READ_ONLY, only read access
134	to its resources is possible.
135
136	The BResources object makes a copy of \a file, that is the caller remains
137	owner of the BFile object.
138*/
139
140
141//! @{
142
143
144/*!
145	\fn status_t BResources::SetTo(const BFile* file, bool clobber)
146	\brief Initializes the BResources object to represent the resources of
147	       the supplied file.
148
149	\param file The file to initialize the BResources object from.
150	\param clobber If \c true, the data of the file are erased.
151
152	\returns A status code.
153	\retval B_OK Everything went fine.
154	\retval B_BAD_VALUE \a file was \c NULL or uninitialized.
155	\retval B_ERROR Failed to initialize the object.
156
157	\since BeOS R3
158*/
159
160
161/*!
162	\fn status_t BResources::SetTo(const char* path, bool clobber)
163	\brief Initialized the BResources object to represent the resources of
164	       the file referred to by the supplied \a path.
165
166	\param path A path referring to the file to create a BResource object
167	       from.
168	\param clobber If \c true, the data of the file are erased.
169
170	\returns A status code.
171	\retval B_OK Everything went fine.
172	\retval B_BAD_VALUE \a path was \c NULL.
173	\retval B_ENTRY_NOT_FOUND The file referenced by \a path couldn't be found.
174	\retval B_ERROR Failed to initialize the object.
175
176	\since Haiku R1
177*/
178
179
180/*!
181	\fn status_t BResources::SetTo(const entry_ref* ref, bool clobber)
182	\brief Initialized the BResources object to represent the resources of the
183	       file referenced by the supplied \a ref.
184
185	\param ref An entry_ref referring to the file to create a BResource object
186	       from.
187	\param clobber If \c true, the data of the file are erased.
188
189	\returns A status code.
190	\retval B_OK Everything went fine.
191	\retval B_BAD_VALUE \a ref was \c NULL.
192	\retval B_ENTRY_NOT_FOUND The file referenced by \a ref couldn't be found.
193	\retval B_ERROR Failed to initialize the object.
194
195	\since Haiku R1
196*/
197
198
199/*!
200	\fn status_t BResources::SetToImage(image_id image, bool clobber)
201	\brief Initialized the BResources object to represent the resources of
202	       the file from which the specified \a image has been loaded.
203
204	If \a clobber is \c true, the file's resources are removed.
205
206	\param image ID of a loaded image.
207	\param clobber If \c true, the data of the file are erased.
208
209	\returns A status code.
210	\retval B_OK Everything went fine.
211	\retval B_ENTRY_NOT_FOUND The file referenced by \a image couldn't be found.
212	\retval B_ERROR Failed to initialize the object.
213
214	\since Haiku R1
215*/
216
217
218/*!
219	\fn status_t BResources::SetToImage(const void* codeOrDataPointer,
220		bool clobber)
221	\brief Initialized the BResources object to represent the resources of
222	       the file from which the specified pointer has been loaded.
223
224	The image belongs to the current team and is identified by a pointer into
225	it's code (aka text) or data segment, i.e. any pointer to a function or a
226	static (or global) variable will do.
227
228	If \a clobber is \c true, the file's resources are removed.
229
230	\param codeOrDataPointer Pointer to the text or data segment of the image.
231	\param clobber If \c true, the data of the file are erased.
232
233	\returns A status code.
234	\retval B_OK Everything went fine.
235	\retval B_BAD_VALUE \a codeOrDataPointer was \c NULL.
236	\retval B_ENTRY_NOT_FOUND The image or the file couldn't be found.
237	\retval B_ERROR Failed to initialize the object.
238
239	\since Haiku R1
240*/
241
242
243//! @}
244
245
246/*!
247	\name Constructor Helpers
248*/
249
250
251//! @{
252
253
254/*!
255	\fn void BResources::Unset()
256	\brief Returns the BResources object to an uninitialized state.
257
258	If the object represented resources that had been modified, the data are
259	written back to the file.
260
261	\note This method is not found in BeOS R5.
262
263	\since Haiku R1
264*/
265
266
267/*!
268	\fn status_t BResources::InitCheck() const
269	\brief Gets the initialization status of the object.
270
271	Unlike other Storage Kit classes a BResources object is always properly
272	initialized, unless it couldn't allocate memory for some important
273	internal structures. Thus even after a call to SetTo() that reported an
274	error, InitCheck() is likely to return \c B_OK.
275
276	\note This method is not found in BeOS R5.
277
278	\return \c B_OK if the objects is properly initialized,
279	        \c B_NO_MEMORY otherwise.
280
281	\since Haiku R1
282*/
283
284
285//! @}
286
287
288/*!
289	\name LoadResources
290
291	A resource is loaded into memory only once. A second call with the same
292	parameters will result in the same pointer. The BResources object is the
293	owner of the allocated memory and the pointer to it will be valid until
294	the object is destroyed or the resource is removed or modified.
295*/
296
297
298//! @{
299
300
301/*!
302	\fn const void* BResources::LoadResource(type_code type, int32 id,
303		size_t* _size)
304	\brief Loads a resource identified by \a type and \a id into memory.
305
306	\param type The type of the resource to be loaded.
307	\param id The ID of the resource to be loaded.
308	\param _size A pointer to a variable into which the size of the resource
309	       shall be written.
310
311	\return A pointer to the resource data if everything went fine, or
312	        \c NULL if the file does not have a resource that matches the
313	        parameters or an error occurred.
314
315	\since BeOS R4
316*/
317
318
319/*!
320	\fn const void* BResources::LoadResource(type_code type, const char* name,
321		size_t* _size)
322	\brief Loads a resource identified by \a type and \a name into memory.
323
324	\note Since a type and name pair may not identify a resource uniquely,
325		  this method always returns the first resource that matches the
326		  parameters, that is the one with the smallest index.
327
328	\param type The type of the resource to be loaded.
329	\param name The name of the resource to be loaded.
330	\param _size A pointer to a variable into which the size of the resource
331		   shall be written.
332
333	\return A pointer to the resource data if everything went fine, or
334	        \c NULL if the file does not have a resource that matches the
335	        parameters or an error occurred.
336
337	\since BeOS R4
338*/
339
340
341/*!
342	\fn status_t BResources::PreloadResourceType(type_code type)
343	\brief Loads all resources of the specified \a type into memory.
344
345	If \a type is 0, all resources are loaded. This might be useful for
346	performance reasons.
347
348	\param type The type of resources to be loaded.
349
350	\returns One of the following status codes or the negation of the number
351	         of errors that occurred.
352	\retval B_OK Everything went fine.
353	\retval B_BAD_FILE The resource map is empty???
354
355	\since BeOS R4
356*/
357
358
359//! @}
360
361
362/*!
363	\fn const BFile& BResources::File() const
364	\brief Gets a reference to the internal BFile object.
365
366	\return A reference to the internal BFile object.
367
368	\since BeOS R4
369*/
370
371
372/*!
373	\fn status_t BResources::Sync()
374	\brief Writes all changes to the resources to the file.
375
376	Since AddResource() and RemoveResource() may change the resources only in
377	memory, this method can be used to make sure, that all changes are
378	actually written to the file.
379
380	The BResources object's destructor calls Sync() before cleaning up.
381
382	\note When a resource is written to the file its data is converted
383	      to the endianness of the file. When reading a resource the
384	      data is converted to the endianness of the host. This of course
385	      only works for known types, i.e. those that swap_data() is able to
386	      understand.
387
388	\returns A status code.
389	\retval B_OK Everything went fine.
390	\retval B_BAD_FILE The resource map is empty???
391	\retval B_FILE_ERROR A file error occurred.
392	\retval B_IO_ERROR An error occurred while writing the resources.
393	\retval B_NOT_ALLOWED The file was opened read only.
394
395	\since BeOS R4
396*/
397
398
399/*!
400	\fn status_t BResources::MergeFrom(BFile* fromFile)
401	\brief Adds the resources of \a fromFile to the internal file of the
402	       BResources object.
403
404	\param fromFile The file whose resources are to be be copied from.
405
406	\returns A status code.
407	\retval B_OK Everything went fine.
408	\retval B_BAD_FILE The resource map is empty???
409	\retval B_BAD_VALUE \a fromFile was \c NULL.
410	\retval B_FILE_ERROR A file error occurred.
411	\retval B_IO_ERROR An error occurred while writing the resources.
412
413	\since BeOS R4
414*/
415
416
417/*!
418	\fn status_t BResources::WriteTo(BFile* file)
419	\brief Writes the resources to a new file.
420
421	The resources formerly contained in the target file (if any) are erased.
422	When the method returns, the BResources object refers to the new file.
423
424	\warning If the resources have been modified, but Sync() has not been
425	         called, the old file remains unmodified.
426
427	\param file The file that the resources shall be written to.
428
429	\return \c B_OK if everything went fine or an error code otherwise.
430
431	\since BeOS R4
432*/
433
434
435/*!
436	\fn status_t BResources::AddResource(type_code type, int32 id,
437		const void* data, size_t length, const char* name)
438	\brief Adds a new resource to the file.
439
440	If a resource already exists with the same \a type and \a id it is
441	replaced. The caller keeps the ownership of the supplied chunk of memory
442	containing the resource data.
443
444	Supplying an empty \a name (\c "") is equivalent to supplying a \c NULL
445	\a name.
446
447	\param type The type of the resource.
448	\param id The ID of the resource.
449	\param data The resource data.
450	\param length The size of the data in bytes.
451	\param name The name of the resource (may be empty or \c NULL).
452
453	\returns A status code.
454	\retval B_OK Everything went fine.
455	\retval B_BAD_VALUE \a data was \c NULL.
456	\retval B_FILE_ERROR A file error occurred.
457	\retval B_NO_MEMORY Not enough memory for the operation.
458	\retval B_NOT_ALLOWED The file was opened read only.
459
460	\since BeOS R3
461*/
462
463
464/*!
465	\fn bool BResources::HasResource(type_code type, int32 id)
466	\brief Returns whether the file contains a resource with the specified
467	       \a type and \a id.
468
469	\param type The resource type to check.
470	\param id The ID of the resource to check.
471
472	\return \c true if the file contains a matching resource,
473	        \c false otherwise.
474
475	\since BeOS R3
476*/
477
478
479/*!
480	\fn bool BResources::HasResource(type_code type, const char* name)
481	\brief Returns whether the file contains a resource with the specified
482	       \a type and \a name.
483
484	\param type The resource type to check.
485	\param name The name of the resource to check.
486
487	\return \c true, if the file contains a matching resource,
488	        \c false otherwise.
489
490	\since BeOS R3
491*/
492
493
494/*!
495	\fn bool BResources::GetResourceInfo(int32 byIndex, type_code* typeFound,
496		int32* idFound, const char** nameFound, size_t* lengthFound)
497	\brief Gets information about a resource identified by \a byindex.
498
499	\param byIndex The index of the resource in the file.
500	\param typeFound A pointer to a variable the type of the found resource
501	       shall be written into.
502	\param idFound A pointer to a variable the ID of the found resource
503	       shall be written into.
504	\param nameFound A pointer to a variable the name pointer of the found
505	       resource shall be written into.
506	\param lengthFound A pointer to a variable the data size of the found
507	       resource shall be written into.
508
509	\return \c true, if a matching resource could be found,
510	        \c false otherwise.
511
512	\since BeOS R3
513*/
514
515
516/*!
517	\fn bool BResources::GetResourceInfo(type_code byType, int32 andIndex,
518		int32* idFound, const char** nameFound, size_t* lengthFound)
519	\brief Gets information about a resource identified by \a byType and
520	       \a andIndex.
521
522	\param byType The resource type.
523	\param andIndex The index into a array of resources of type \a byType.
524	\param idFound A pointer to a variable the ID of the found resource
525	       shall be written into.
526	\param nameFound A pointer to a variable the name pointer of the found
527	       resource shall be written into.
528	\param lengthFound A pointer to a variable the data size of the found
529	       resource shall be written into.
530
531	\return \c true, if a matching resource could be found,
532	        \c false otherwise.
533
534	\since BeOS R3
535*/
536
537
538/*!
539	\fn bool BResources::GetResourceInfo(type_code byType, int32 andID,
540		const char** nameFound, size_t* lengthFound)
541	\brief Gets information about a resource identified by \a byType and
542	       \a andID.
543
544	\param byType The resource type.
545	\param andID The resource ID.
546	\param nameFound A pointer to a variable the name pointer of the found
547	       resource shall be written into.
548	\param lengthFound A pointer to a variable the data size of the found
549	       resource shall be written into.
550
551	\return \c true, if a matching resource could be found,
552	        \c false otherwise.
553
554	\since BeOS R3
555*/
556
557
558/*!
559	\fn bool BResources::GetResourceInfo(type_code byType, const char* andName,
560		int32* idFound, size_t* lengthFound)
561	\brief Gets information about a resource identified by \a byType and
562	       \a andName.
563
564	\param byType The resource type.
565	\param andName The resource name.
566	\param idFound A pointer to a variable the ID of the found resource
567	       shall be written into.
568	\param lengthFound A pointer to a variable the data size of the found
569	       resource shall be written into.
570
571	\return \c true, if a matching resource could be found,
572	        \c false otherwise.
573
574	\since BeOS R3
575*/
576
577
578/*!
579	\fn bool BResources::GetResourceInfo(const void* byPointer,
580		type_code* typeFound, int32* idFound, size_t* lengthFound,
581		const char** nameFound)
582	\brief Gets information about a resource identified by \a byPointer.
583
584	\param byPointer The pointer to the resource data (formerly returned by
585	       LoadResource()).
586	\param typeFound A pointer to a variable the type of the found resource
587	       shall be written into.
588	\param idFound A pointer to a variable the ID of the found resource
589	       shall be written into.
590	\param lengthFound A pointer to a variable the data size of the found
591	       resource shall be written into.
592	\param nameFound A pointer to a variable the name pointer of the found
593	       resource shall be written into.
594
595	\return \c true, if a matching resource could be found,
596	        \c false otherwise.
597
598	\since BeOS R4
599*/
600
601
602/*!
603	\fn status_t BResources::RemoveResource(const void* resource)
604	\brief Removes a resource identified by \a resource.
605
606	\param resource The pointer to the resource data (formerly returned by
607	       LoadResource()).
608
609	\return A status code.
610	\retval B_OK Everything went fine.
611	\retval B_BAD_VALUE \a resource was \c NULL or invalid (didn't point to
612	        any resource data of this file).
613	\retval B_ERROR An error occurred while removing the resource.
614	\retval B_FILE_ERROR A file error occurred.
615	\retval B_NOT_ALLOWED The file was opened read only.
616
617	\since BeOS R4
618*/
619
620
621/*!
622	\fn status_t BResources::RemoveResource(type_code type, int32 id)
623	\brief Removes a resource identified by \a type and \a id.
624
625	\param type The type of the resource to remove.
626	\param id The ID of the resource to remove.
627
628	\return A status code.
629	\retval B_OK Everything went fine.
630	\retval B_BAD_VALUE No such resource was found.
631	\retval B_ERROR An error occurred while removing the resource.
632	\retval B_FILE_ERROR A file error occurred.
633	\retval B_NOT_ALLOWED The file was opened read only.
634
635	\since BeOS R3
636*/
637
638
639/*!
640	\name Deprecated Methods
641
642	These methods are deprecated and should not be used as there is a better
643	method. See the method description for the replacement method to use.
644*/
645
646
647//! @{
648
649
650/*!
651	\fn status_t BResources::WriteResource(type_code type, int32 id,
652		const void* data, off_t offset, size_t length)
653	\brief Writes data into an existing resource.
654	       (deprecated, use AddResource() instead)
655
656	\deprecated Use AddResource() instead.
657
658	If writing the data would exceed the bounds of the resource, it is
659	enlarged respectively. If \a offset is past the end of the resource,
660	padding with unspecified data is inserted.
661
662	\param type The type of the resource to write data to.
663	\param id The ID of the resource to write data to.
664	\param data The data to be written.
665	\param offset The byte offset relative to the beginning of the resource at
666	       which the data shall be written.
667	\param length The size of the data to be written.
668
669	\return A status code.
670	\retval B_OK Everything went fine.
671	\retval B_BAD_VALUE \a data was \c NULL or \a type and \a id did not
672	        identify an existing resource.
673	\retval B_ERROR Error writing data.
674	\retval B_NO_MEMORY Not enough memory for this operation.
675
676	\since BeOS R3
677*/
678
679
680/*!
681	\fn status_t BResources::ReadResource(type_code type, int32 id,
682		void* data, off_t offset, size_t length)
683	\brief Reads data from an existing resource.
684	       (deprecated, use LoadResource() instead)
685
686	\deprecated Use LoadResource() instead.
687
688	If more data than existing are requested, this method does not fail. It
689	will then read only the existing data. As a consequence an offset past
690	the end of the resource will not cause the method to fail, but no data
691	will be read at all.
692
693	\param type The type of the resource to be read.
694	\param id The ID of the resource to be read.
695	\param data A pointer to a buffer into which the data shall be read
696	\param offset The byte offset relative to the beginning of the resource
697	       from which the data shall be read.
698	\param length The size of the data to be read.
699
700	\return A status code.
701	\retval B_OK Everything went fine.
702	\retval B_BAD_VALUE \a data was \c NULL or \a type and \a id did not
703	        identify an existing resource.
704	\retval B_ERROR Error reading data.
705	\retval B_NO_MEMORY Not enough memory for this operation.
706
707	\since BeOS R3
708*/
709
710
711/*!
712	\fn void* BResources::FindResource(type_code type, int32 id,
713		size_t* lengthFound)
714	\brief Finds a resource by \a type and \a id and returns a pointer to a
715	       copy of its data. (deprecated, use LoadResource() instead)
716
717	\deprecated Use LoadResource() instead.
718
719	\warning The caller is responsible for calling free() to release the
720	         memory used by the returned data.
721
722	\param type The type of the resource to find.
723	\param id The ID of the resource to find.
724	\param lengthFound A pointer to a variable into which the size of the
725	       resource data shall be written.
726
727	\return A pointer to the resource data if everything went fine or \c NULL
728	        if an error occurred.
729
730	\since BeOS R3
731*/
732
733
734/*!
735	\fn void* BResources::FindResource(type_code type, const char* name,
736		size_t* lengthFound)
737	\brief Finds a resource by \a type and \a name and returns a pointer to a
738	       copy of its data. (deprecated, use LoadResource() instead)
739
740	\deprecated Use LoadResource() instead.
741
742	\warning The caller is responsible for calling free() to release the
743	         memory used by the returned data.
744
745	\param type The type of the resource to find.
746	\param name The name of the resource to find.
747	\param lengthFound A pointer to a variable into which the size of the
748	       resource data shall be written.
749
750	\return A pointer to the resource data if everything went fine or \c NULL
751	        if an error occurred.
752
753	\since BeOS R3
754*/
755
756
757//! @}
758