1 /*
2  * $Id: ebmldate.c 642 2010-11-28 08:38:47Z robux4 $
3  * Copyright (c) 2008-2010, Matroska (non-profit organisation)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *     * Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above copyright
11  *       notice, this list of conditions and the following disclaimer in the
12  *       documentation and/or other materials provided with the distribution.
13  *     * Neither the name of the Matroska assocation nor the
14  *       names of its contributors may be used to endorse or promote products
15  *       derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY the Matroska association ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL The Matroska Foundation BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include "ebml/ebml.h"
29 #include "ebml/ebml_internal.h"
30 
EBML_DateTime(const ebml_date * Element)31 datetime_t EBML_DateTime(const ebml_date *Element)
32 {
33     assert(Node_IsPartOf(Element,EBML_DATE_CLASS));
34     if (!Element->Base.bValueIsSet)
35         return 0;
36     return (datetime_t)Scale32(Element->Value,1,1000000000); // nanoseconds to seconds
37 }
38 
EBML_DateSetDateTime(ebml_date * Element,datetime_t Date)39 err_t EBML_DateSetDateTime(ebml_date *Element, datetime_t Date)
40 {
41     if (Date == INVALID_DATETIME_T)
42         return ERR_INVALID_PARAM;
43     EBML_IntegerSetValue(Element, Scale64(Date,1000000000,1)); // seconds to nanoseconds
44     return ERR_NONE;
45 }
46 
ValidateSize(const ebml_element * p)47 static bool_t ValidateSize(const ebml_element *p)
48 {
49     return EBML_ElementIsFiniteSize(p) && (p->DataSize == 8 || p->DataSize == 0);
50 }
51 
ReadData(ebml_date * Element,stream * Input,const ebml_parser_context * ParserContext,bool_t AllowDummyElt,int Scope,size_t DepthCheckCRC)52 static err_t ReadData(ebml_date *Element, stream *Input, const ebml_parser_context *ParserContext, bool_t AllowDummyElt, int Scope, size_t DepthCheckCRC)
53 {
54     err_t Result;
55     int DataSize;
56     uint8_t Value[8];
57 
58     Element->Base.bValueIsSet = 0;
59 
60     if (Scope == SCOPE_NO_DATA)
61         return ERR_NONE;
62 
63     if (Stream_Seek(Input,EBML_ElementPositionData((ebml_element*)Element),SEEK_SET)==INVALID_FILEPOS_T)
64     {
65         Result = ERR_READ;
66         goto failed;
67     }
68 
69     assert(Element->Base.DataSize<=8);
70     Result = Stream_Read(Input,Value,(size_t)Element->Base.DataSize,NULL);
71     if (Result != ERR_NONE)
72         goto failed;
73 
74 #ifdef IS_BIG_ENDIAN
75     memcpy(&Element->Value,Value,Element->Base.DataSize);
76 #else
77     Element->Value = 0;
78     for (DataSize=0;DataSize<Element->Base.DataSize;++DataSize)
79         ((uint8_t*)&Element->Value)[DataSize] = Value[Element->Base.DataSize-DataSize-1];
80 #endif
81     Element->Base.bValueIsSet = 1;
82 failed:
83     return Result;
84 }
85 
PostCreate(ebml_date * Element,bool_t SetDefault)86 static void PostCreate(ebml_date *Element, bool_t SetDefault)
87 {
88     INHERITED(Element,ebml_element_vmt,EBML_DATE_CLASS)->PostCreate(Element, SetDefault);
89     Element->Base.DefaultSize = 8;
90     Element->Base.bNeedDataSizeUpdate = 0;
91 }
92 
93 META_START(EBMLDate_Class,EBML_DATE_CLASS)
94 META_VMT(TYPE_FUNC,ebml_element_vmt,PostCreate,PostCreate)
95 META_VMT(TYPE_FUNC,ebml_element_vmt,ValidateSize,ValidateSize)
96 META_VMT(TYPE_FUNC,ebml_element_vmt,ReadData,ReadData)
97 META_END(EBML_SINTEGER_CLASS)
98