1 /*
2    Source File : DictionaryContext.cpp
3 
4 
5    Copyright 2011 Gal Kahana PDFWriter
6 
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10 
11        http://www.apache.org/licenses/LICENSE-2.0
12 
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 
19 
20 */
21 #include "DictionaryContext.h"
22 #include "ObjectsContext.h"
23 #include "Trace.h"
24 #include "IByteWriterWithPosition.h"
25 
26 
27 using namespace PDFHummus;
28 
29 static const std::string scStartDictionary = "<<";
30 static const std::string scEndDictionary = ">>";
31 
32 
DictionaryContext(ObjectsContext * inObjectsContext,size_t inIndentLevel)33 DictionaryContext::DictionaryContext(ObjectsContext* inObjectsContext,size_t inIndentLevel)
34 {
35 	mObjectsContext = inObjectsContext;
36 	mIndentLevel= inIndentLevel;
37 
38 	mObjectsContext->WriteKeyword(scStartDictionary);
39 }
40 
~DictionaryContext(void)41 DictionaryContext::~DictionaryContext(void)
42 {
43 	if(mIndentLevel > 0)
44 	{
45 		--mIndentLevel; // the final end dictionary should be written with a lower indent, as a value of the container
46 		WriteIndents();
47 	}
48 	mObjectsContext->WriteKeyword(scEndDictionary);
49 }
50 
WriteKey(const std::string & inKey)51 EStatusCode DictionaryContext::WriteKey(const std::string& inKey)
52 {
53 	if(mKeys.find(inKey) == mKeys.end())
54 	{
55 		WriteIndents();
56 		mObjectsContext->WriteName(inKey);
57 		mKeys.insert(inKey);
58 		return PDFHummus::eSuccess;
59 	}
60 	else
61 	{
62 		TRACE_LOG1("DictionaryContext::WriteKey, Duplicate key error. Cannot write multiple keys in the same dictionary. key reused - %s",inKey.c_str());
63 		return PDFHummus::eFailure;
64 	}
65 }
66 
67 static const Byte scTab[1] = {'\t'};
WriteIndents()68 void DictionaryContext::WriteIndents()
69 {
70 	IByteWriterWithPosition* outputStream = mObjectsContext->StartFreeContext();
71 	for(size_t i=0;i<=mIndentLevel;++i)
72 		outputStream->Write(scTab,1);
73 	mObjectsContext->EndFreeContext();
74 }
75 
WriteIntegerValue(long long inValue)76 void DictionaryContext::WriteIntegerValue(long long inValue)
77 {
78 	mObjectsContext->WriteInteger(inValue,eTokenSeparatorEndLine);
79 }
80 
WriteObjectReferenceValue(const ObjectReference & inObjectReference)81 void DictionaryContext::WriteObjectReferenceValue(const ObjectReference& inObjectReference)
82 {
83     WriteObjectReferenceValue(inObjectReference.ObjectID,inObjectReference.GenerationNumber);
84 }
85 
WriteObjectReferenceValue(ObjectIDType inObjectReference,unsigned long inGenerationNumber)86 void DictionaryContext::WriteObjectReferenceValue(ObjectIDType inObjectReference,unsigned long inGenerationNumber)
87 {
88     mObjectsContext->WriteIndirectObjectReference(inObjectReference,inGenerationNumber,eTokenSeparatorEndLine);
89 }
90 
91 
WriteNewObjectReferenceValue(ObjectIDType inObjectReference)92 void DictionaryContext::WriteNewObjectReferenceValue(ObjectIDType inObjectReference)
93 {
94     WriteObjectReferenceValue(inObjectReference,0);
95 }
96 
WriteLiteralStringValue(const std::string & inValue)97 void DictionaryContext::WriteLiteralStringValue(const std::string& inValue)
98 {
99 	mObjectsContext->WriteLiteralString(inValue,eTokenSeparatorEndLine);
100 }
101 
WriteKeywordValue(const std::string & inValue)102 void DictionaryContext::WriteKeywordValue(const std::string& inValue)
103 {
104 	mObjectsContext->WriteKeyword(inValue);
105 }
106 
107 
WriteHexStringValue(const std::string & inValue)108 void DictionaryContext::WriteHexStringValue(const std::string& inValue)
109 {
110 	mObjectsContext->WriteHexString(inValue,eTokenSeparatorEndLine);
111 }
112 
WriteNullValue()113 void DictionaryContext::WriteNullValue()
114 {
115 	mObjectsContext->WriteNull(eTokenSeparatorEndLine);
116 }
117 
WriteNameValue(const std::string & inValue)118 void DictionaryContext::WriteNameValue(const std::string& inValue)
119 {
120 	mObjectsContext->WriteName(inValue,eTokenSeparatorEndLine);
121 }
122 
WriteRectangleValue(const PDFRectangle & inRectangle)123 void DictionaryContext::WriteRectangleValue(const PDFRectangle& inRectangle)
124 {
125 	mObjectsContext->StartArray();
126 	mObjectsContext->WriteDouble(inRectangle.LowerLeftX);
127 	mObjectsContext->WriteDouble(inRectangle.LowerLeftY);
128 	mObjectsContext->WriteDouble(inRectangle.UpperRightX);
129 	mObjectsContext->WriteDouble(inRectangle.UpperRightY);
130 	mObjectsContext->EndArray();
131 	mObjectsContext->EndLine();
132 }
133 
WriteDoubleValue(double inValue)134 void DictionaryContext::WriteDoubleValue(double inValue)
135 {
136 	mObjectsContext->WriteDouble(inValue,eTokenSeparatorEndLine);
137 }
138 
WriteBooleanValue(bool inValue)139 void DictionaryContext::WriteBooleanValue(bool inValue)
140 {
141 	mObjectsContext->WriteBoolean(inValue,eTokenSeparatorEndLine);
142 }
143